#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <math.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include "ApiBaseInfo.h"
#include "zlog.h"
#include "iniparser.h"
#include "microApp.h"
#include "security_manage.h"
#include "docker.h"
#include "common.h"

// 运行数据事件单元定义
typedef struct _S_DATA_REPORT_CMD_UNIT
{
	S_DATA_REPORT_CMD sdataRepordCmd;
	time_t lastSampleTime;
	time_t lastReportTime;
} S_DATA_REPORT_CMD_UNIT, * PS_DATA_REPORT_CMD_UNIT;

typedef struct PACKED // 定义一个cpu occupy的结构体
{

	char name[20]; // 定义一个char类型的数组名name有20个元素

	unsigned int user; // 定义一个无符号的int类型的user

	unsigned int nice; // 定义一个无符号的int类型的nice

	unsigned int system; // 定义一个无符号的int类型的system

	unsigned int idle; // 定义一个无符号的int类型的idle

} CPU_OCCUPY;

typedef struct PACKED1 // 定义一个mem occupy的结构体
{

	char name[20]; // 定义一个char类型的数组名name有20个元素

	unsigned long total;

	char name2[20];

	unsigned long free;

} MEM_OCCUPY;
typedef void (*pFunCommen)(PS_DATA_REPORT_PARAM);
#define SYS_DISK_BUFF_LEN 256
#define SYS_DISK_NAME_LEN 80
#define SYS_100_PERSENT 100
#define MAC_ADDR_LEN 6

/// 全局
static S_DATA_REPORT_CMD_UNIT g_dataReportCmd[32] = { 0 };
// static int g_dataReportCmdCount = 0;
static S_DATA_REPORT_PARAM g_dataCommen[5] = { 0 };
static S_DATA_REPORT_PARAM g_realTime_cpuUsage = { 0 };
static S_DATA_REPORT_PARAM g_realTime_cpuTemp = { 0 };
static S_DATA_REPORT_4G g_realTime_4G = { 0 };
static S_DATA_REPORT_PROCESS g_realTime_cpuTop5[6] = { 0 };
static S_DATA_REPORT_PROCESS g_realTime_memTop5[5] = { 0 };
static double g_dataNetwork[100] = { 0 };
static int g_dataNetworkCount = 0;
static int g_dataNetTtl = 0;
static char g_dataNetIp[65];
static int g_old_process_count = 0;
static S_DATA_REPORT_PROCESS g_old_process[330] = { 0 };
// static int g_old_server_count = 0;
// static S_DATA_REPORT_SERVER g_old_server[250] = {0};
static int g_old_port_count = 0;
static S_DATA_REPORT_PORT g_old_port[200] = { 0 };
static S_DATA_REPORT_WIRE g_old_wire[32] = { 0 };
static int g_old_wire_count = 0;
static int g_start_flag[3] = { 0 };
static int g_disk_total = 0;
static char g_error[65] = { 0 };
static pthread_mutex_t mutex;
S_4GModule g_s_4GModule[3] = { 0 };//最多2个
static dictionary* terminalini = NULL;
extern int file_sencrypt;
extern dictionary* iniMqtt;
extern char mqtt_ini[128];
extern ob_context g_mqtt_ob;
extern char g_ServerIp[64];
extern void QueryCcoSubDevice();

/// 全局
double g_dev_total = 0;
int iottls_int = -1;
int g_first_check = 0;

custom_timer_t custom_timer[3]; // 定义一个全局变量来存储定时器句柄和新的间隔时间
uv_loop_t* global_loop;
static uv_async_t async_handle;
static uv_async_t async_handle_gather;
time_t monitor_start_time;
bool async_handle_start = false;

typedef struct
{
	uv_work_t req;
	// 可添加其他字段
} work_data_t;


int interfaces_count = 0;
NetInterface realTimeprev = { 0 };

static int confTerminal(char* key, char* value, int flag)
{
	if (!terminalini)
	{
		terminalini = iniparser_load("./conf/terminal.ini");
		if (!terminalini)
		{
			return -1;
		}
	}
	if (!flag)
	{
		char* value2 = iniparser_getstring(terminalini, key, NULL);
		if (value2 == NULL)
		{
			return -2;
		}
		strcpy(value, value2);
	}
	if (flag)
	{
		char tmp[64] = { 0 };
		snprintf(tmp, sizeof(tmp), "%s", "samplefrequency");
		iniparser_set(terminalini, tmp, NULL); // 创建section
		snprintf(tmp, sizeof(tmp), "%s", "reportfrequency");
		iniparser_set(terminalini, tmp, NULL); // 创建section
		int ret = iniparser_set(terminalini, key, value);
		if (ret == -1)
		{
			return -3;
		}
		FILE* ini_file = fopen("./conf/terminal.ini", "w");
		if (ini_file)
		{
			iniparser_dump_ini(terminalini, ini_file);
			fclose(ini_file);
		}
	}
	iniparser_freedict(terminalini);
	terminalini = NULL;
	return 0;
}

//提供接口释放资源(临时)
static void freeConfTerminalIni()
{
	if (terminalini != NULL)
	{
		iniparser_freedict(terminalini);
		terminalini = NULL;
	}
}
int getConfTerminal(char* key, char* value)
{
	return confTerminal(key, value, 0);
}
int setConfTerminalString(char* key, char* value)
{
	return confTerminal(key, value, 1);
}
int setConfTerminal(char* key, int value)
{
	char buf[64] = { 0 };
	sprintf(buf, "%d", value);
	return setConfTerminalString(key, buf);
}
int setNetIp(char* ip)
{
	strcpy(g_dataNetIp, ip);
	return 0;
}
double get_sysDiskUsage()
{
	FILE* fp;
	char filesystem[SYS_DISK_NAME_LEN], available[SYS_DISK_NAME_LEN], use[SYS_DISK_NAME_LEN], mounted[SYS_DISK_NAME_LEN], buf[SYS_DISK_BUFF_LEN];
	double used, blocks, used_rate;
	fp = popen("df", "r");
	fgets(buf, SYS_DISK_BUFF_LEN, fp);
	double dev_total = 0, dev_used = 0;
	while (6 == fscanf(fp, "%s %lf %lf %s %s %s", filesystem, &blocks, &used, available, use, mounted))
	{
		dev_total += blocks;
		dev_used += used;
	}
	g_dev_total = dev_total;
	used_rate = (dev_used / dev_total) * SYS_100_PERSENT;
	pclose(fp);


	return used_rate;
}

/*获取内存使用率*/
float get_memoccupy(MEM_OCCUPY* mem) // 对无类型get函数含有一个形参结构体类弄的指针
{

	FILE* fd;

	int n;

	char buff[256];

	char buff1[256];

	char buff2[256];

	char buff3[256];

	char buff4[256];

	MEM_OCCUPY* m;

	m = mem;

	float mem_use;
	fd = fopen("/proc/meminfo", "r");
	fgets(buff1, sizeof(buff1), fd);
	int num1 = atoi(buff1 + 15);
	fgets(buff2, sizeof(buff2), fd);
	int num2 = atoi(buff2 + 15);
	fgets(buff3, sizeof(buff3), fd);
	int num3 = atoi(buff3 + 15);
	fgets(buff4, sizeof(buff4), fd);
	int num4 = atoi(buff4 + 15);
	fgets(buff, sizeof(buff), fd); // 从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里
	int num5 = atoi(buff + 15);
	// 内存使用率(MEMUsedPerc)=100*(MemTotal-MemFree-Buffers-Cached)/MemTotal

	mem_use = (float)100 * (num1 - num2 - num5 - num4) / num1;

	// printf("内存使用率为：%.2f%%\n",mem_use);

	fclose(fd); // 关闭文件fd
	return mem_use;
}

/*获取cpu使用率*/
float cal_cpuoccupy(CPU_OCCUPY* o, CPU_OCCUPY* n)
{
	double od, nd;
	double id, sd;
	float cpu_use = 0;
	od = (unsigned long)(o->user + o->nice + o->system + o->idle); // 第一次(用户+优先级+系统+空闲)的时间再赋给od
	nd = (unsigned long)(n->user + n->nice + n->system + n->idle); // 第二次(用户+优先级+系统+空闲)的时间再赋给nd
	id = (unsigned long)(n->user - o->user);					   // 用户第一次和第二次的时间之差再赋给id
	sd = (unsigned long)(n->system - o->system);				   // 系统第一次和第二次的时间之差再赋给sd
	if ((nd - od) != 0)
	{
		cpu_use = (float)((sd + id) * 100) / (nd - od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
	}
	else
	{
		cpu_use = 0;
	}
	// dzlog_info("cal_cpuoccupy cpu_use[%f]", cpu_use);
	return cpu_use;
}

void get_cpuoccupy(CPU_OCCUPY* cpust) // 对无类型get函数含有一个形参结构体类弄的指针O
{
	FILE* fd;
	int n;
	char buff[256];
	CPU_OCCUPY* cpu_occupy;
	cpu_occupy = cpust;
	fd = fopen("/proc/stat", "r");
	fgets(buff, sizeof(buff), fd);
	sscanf(buff, "%s %llu %llu %llu %llu", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice, &cpu_occupy->system, &cpu_occupy->idle);
	fclose(fd);
}

int testFun(int test)
{
	printf("%d\n", test);
	system("date");
	return 0;
}

int popenCmd(char* cmd, char* result)
{
	if (!cmd || strlen(cmd) == 0)
	{
		return -1;
	}
	FILE* read_fp = popen(cmd, "r");
	if (read_fp == NULL)
	{
		dzlog_error("popenCmd start popen error");
		return -3;
	}
	char buf[512];
	memset(buf, 0, sizeof(buf));
	int len = fread(buf, 1, 512, read_fp);
	if (len <= 0)
	{
		dzlog_error("popenCmd cmd[%s] buf is null", cmd);
		pclose(read_fp);
		return -5;
	}
	strcpy(result, buf);
	//strncpy(result, buf, len);
	pclose(read_fp);
	return 0;
}

// 如果本机的IP地址绑定在第一块网卡上，则只需指定网卡名称，无需获取所有网卡的信息即可获取
int get_localip(const char* eth_name, char* local_ip_addr)
{
	int ret = -1;
	register int fd;
	struct ifreq ifr;

	if (local_ip_addr == NULL || eth_name == NULL)
	{
		return ret;
	}

	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) > 0)
	{
		strcpy(ifr.ifr_name, eth_name);
		if (!(ioctl(fd, SIOCGIFADDR, &ifr)))
		{
			ret = 0;
			strcpy(local_ip_addr, inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));
		}
	}

	if (fd > 0)
	{
		close(fd);
	}
	return ret;
}
// 获取网卡对应IP地址[其中eth是网卡名字 如“eth0” “eth1” "en0" "en1"等, ipstr是输出参数]
// 获取指定网络接口的ip地址;
int get_local_ip(const char* eth_inf, char* ipstr)
{
	int sd;
	struct sockaddr_in sin;
	struct ifreq ifr;

	sd = socket(AF_INET, SOCK_DGRAM, 0);
	if (-1 == sd)
	{
		// printf("socket error: %s\n", strerror(errno));
		return -1;
	}

	strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);
	ifr.ifr_name[IFNAMSIZ - 1] = 0;

	// if error: No such device;
	if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)
	{
		// printf("ioctl error: %s\n", strerror(errno));
		close(sd);
		return -2;
	}

	memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
	snprintf(ipstr, 65, "%s", inet_ntoa(sin.sin_addr));
	close(sd);
	return 0;
}
// 获取指定网络接口的mac地址;
int get_local_mac(const char* eth_inf, char* mac)
{
	int sd;
	struct ifreq ifr;

	bzero(&ifr, sizeof(struct ifreq));
	if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		// printf("get %s mac address socket creat error\n", eth_inf);
		return -1;
	}

	strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);
	if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
	{
		// printf("get %s mac address error\n", eth_inf);
		close(sd);
		return -1;
	}

	snprintf(mac, 128, "%02x:%02x:%02x:%02x:%02x:%02x",
		(unsigned char)ifr.ifr_hwaddr.sa_data[0],
		(unsigned char)ifr.ifr_hwaddr.sa_data[1],
		(unsigned char)ifr.ifr_hwaddr.sa_data[2],
		(unsigned char)ifr.ifr_hwaddr.sa_data[3],
		(unsigned char)ifr.ifr_hwaddr.sa_data[4],
		(unsigned char)ifr.ifr_hwaddr.sa_data[5]);

	close(sd);
	return 0;
}
// 获取指定网络接口的gateway;
int get_local_gateway(const char* eth_inf, char* gateway)
{
	FILE* fp;
	char buffer[1024];
	char* default_gateway = NULL;
	int bytes_read;

	fp = popen("ip route | awk '/default/ { print $3 }'", "r");
	if (fp == NULL)
	{
		printf("Failed to run command\n");
		return -1;
	}

	bytes_read = fread(buffer, 1, sizeof(buffer), fp);
	if (bytes_read > 0)
	{
		buffer[bytes_read - 1] = '\0'; // 移除末尾的换行符
		strcpy(gateway, buffer);
	}

	pclose(fp);
	return 0;
}

int cpuModel(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("uname -m", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int cpuArch(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("uname -m", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int cpuCount(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("cat /proc/cpuinfo |grep \"processor\"|wc -l", result);
	dzlog_info("terminalManage cpuCount ret[%d] result[%s]", ret, result);
	return ret;
}
int cpuCores(char* result)
{
	if (!result)
	{
		return -1;
	}
	long num_cores = sysconf(_SC_NPROCESSORS_ONLN);
	if (num_cores < 0)
	{

		return -1;
	}
	sprintf(result, "%ld", num_cores);

	return 0;
}

int cpuFrequency(char* result)
{
	if (!result)
	{
		return -1;
	}
	char buf[256] = { 0 };
	FILE* fp = NULL;
	int flag = 0;
	if ((fp = popen("devinfo -a", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag++ == 6)
		{
			strcpy(result, buf);
			(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		}
	}
	char* p = strstr(result, "CPU(MHz): ");
	if (p)
	{
		sprintf(result, "%sMHz", p + strlen("CPU(MHz): "));
	}
	pclose(fp);

	return 0;
}

int firmwareVersion(char* result)
{
	char buf[256] = { 0 };
	FILE* fp = NULL;
	int flag = 0;
	if (!result)
	{
		return -1;
	}
	if ((fp = popen("devinfo -a", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		// if(flag++ == 7)
		if (strstr(buf, "firmware version: "))
		{
			strcpy(result, buf);
			(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		}
	}
	pclose(fp);
	char* p = strstr(result, "firmware version: ");
	if (p)
	{
		strcpy(result, p + strlen("firmware version: "));
	}
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return 0;
}


int memCapacity(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("awk \'$3==\"kB\"{$2=$2/1024;$3=\"MB\"} 1\' /proc/meminfo | grep MemTotal", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	// printf("memCapacity result[%s]\n", result);
	char* p = strstr(result, "MemTotal: ");
	if (p)
	{
		p += strlen("MemTotal: ");
		char buf[32] = { 0 };
		strcpy(buf, p);
		strcpy(result, buf);
		// printf("memCapacity p[%s]\n", p);
	}

	return ret;
}
int diskCapacity(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("df -m | awk \'{a+=$2}END{print a}\'", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	strcat(result, "MB");
	return ret;
}
int osKernelVer(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("uname -r", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int osReleaseName(char* result)
{
	if (!result)
	{
		return -1;
	}
	FILE* fp = NULL;
	char buf[255] = { 0 };
	if ((fp = popen("cat /etc/os-release", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* p1 = strstr(buf, "PRETTY_NAME=\"");

		if (p1)
		{
			p1 += strlen("PRETTY_NAME=\"");
			char* p2 = strstr(p1, "(");
			!p2 && (p2 = strstr(p1, "\""));
			if (p2)
			{
				*p2 = '\0';
				strcpy(result, p1);
				// dzlog_info("osReleaseName = %s", p1);
			}
		}
	}
	pclose(fp);

	return 0;
}
int osVersion(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("uname -nrs", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}

int osVersion_V1(char* result)
{
	if (!result)
	{
		return -1;
	}
	FILE* fp = NULL;
	char buf[255] = { 0 };
	char VERSION_ID[16] = { 0 };
	char PRETTY_NAME[32] = { 0 };
	if ((fp = popen("cat /etc/os-release", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* p1 = strstr(buf, "PRETTY_NAME=\"");
		if (p1)
		{
			p1 += strlen("PRETTY_NAME=\"");
			char* p2 = strstr(p1, "(");
			!p2 && (p2 = strstr(p1, "\""));
			if (p2)
			{
				*p2 = '\0';
				strcpy(PRETTY_NAME, p1);
			}
		}

		char* p21 = strstr(buf, "VERSION_ID=");
		if (p21)
		{
			p21 += strlen("VERSION_ID=");
			char* p22 = strstr(p21, "\n");
			if (p22)
			{
				*p22 = '\0';
			}
			strcpy(VERSION_ID, p21);
		}
	}
	strcat(result, PRETTY_NAME);
	strcat(result, " ");
	strcat(result, VERSION_ID);
	dzlog_info("osVersion_V1 result[%s]", result);

	pclose(fp);
	return 0;
}

// 辅助函数：将IPv6前缀（netmask）转换为CIDR前缀长度（如64）
static int ipv6_netmask_to_prefix(const char* ipv6_netmask)
{
	struct in6_addr netmask;
	if (inet_pton(AF_INET6, ipv6_netmask, &netmask) != 1)
	{
		dzlog_error("Invalid IPv6 netmask: %s", ipv6_netmask);
		return -1;
	}

	int prefix_len = 0;
	// 遍历128位前缀（16字节），计算连续1的位数
	for (int i = 0; i < 16; i++)
	{
		if (netmask.s6_addr[i] == 0xff)
		{
			prefix_len += 8; // 完整字节为1，加8位
		}
		else if (netmask.s6_addr[i] == 0x00)
		{
			break; // 遇到0字节，停止计算
		}
		else
		{
			// 部分字节为1，计算剩余位数（如0xf0 -> 4位）
			uint8_t byte = netmask.s6_addr[i];
			while (byte & 0x80) // 从高位到低位检查
			{
				prefix_len++;
				byte <<= 1;
			}
			break;
		}
	}
	return prefix_len;
}

int wiredModules(PS_NETCARD result)
{
	if (!result)
	{
		return -1;
	}
	struct ifaddrs* ifAddrStruct = NULL;
	struct ifaddrs* ifa = NULL;
	void* tmpAddrPtr = NULL;
	int count = 0;

	getifaddrs(&ifAddrStruct);
	for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
	{
		if (!ifa->ifa_addr)
		{
			continue;
		}
		if (strncmp(ifa->ifa_name, "e", 1) != 0 && strncmp(ifa->ifa_name, "b", 1) != 0)
		{
			continue;
		}

		// 检查是否已记录过该网卡  eth0 有ipv4和ipv6两条数据,优先ipv4, eth1 只有ipv6
		int found = 0;
		for (int i = 0; i < count; i++) {
			if (strcmp(result[i].iface, ifa->ifa_name) == 0) {
				found = 1;
				break;
			}
		}
		if (found) continue; // 跳过已处理的网卡

		char mac[128];
		int ret = get_local_mac(ifa->ifa_name, mac);
		if (ret == 0)
		{
			strcpy(result[count].iface, ifa->ifa_name);
			strcpy(result[count].mac, mac);
		}
		else {
			continue;
		}

		if (ifa->ifa_addr->sa_family == AF_INET) // check it is IP4
		{
			tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
			char addressBuffer[INET_ADDRSTRLEN];
			inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);

			char gateway[128];
			ret = get_local_gateway(ifa->ifa_name, gateway);
			if (ret == 0)
			{
				strcpy(result[count].gateway, gateway);
			}
			strcpy(result[count].ip, addressBuffer);

			tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
			char netmaskBuffer[INET_ADDRSTRLEN];
			inet_ntop(AF_INET, tmpAddrPtr, netmaskBuffer, INET_ADDRSTRLEN);
			strcpy(result[count].netmask, netmaskBuffer);
			count++;
		}
		else if (ifa->ifa_addr->sa_family == AF_INET6) // check it is IP6
		{
			// is a valid IP6 Address
			// continue;
			tmpAddrPtr = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
			char addressBuffer[INET6_ADDRSTRLEN];
			if (inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN) == NULL)
			{
				dzlog_error("Failed to convert IPv6 address for interface %s", ifa->ifa_name);
				continue;
			}

			//  过滤环回地址(::1)和链路本地地址(fe80::)
			// if (strstr(addressBuffer, "::1") != NULL || strstr(addressBuffer, "fe80::") != NULL)
			// {
			//     continue;
			// }
			strcpy(result[count].ip, addressBuffer);

			// 获取IPv6前缀（类似子网掩码）并转换为前缀长度
			if (ifa->ifa_netmask != NULL && ifa->ifa_netmask->sa_family == AF_INET6)
			{
				struct sockaddr_in6* netmask6 = (struct sockaddr_in6*)ifa->ifa_netmask;
				char netmaskBuffer[INET6_ADDRSTRLEN];
				inet_ntop(AF_INET6, &netmask6->sin6_addr, netmaskBuffer, INET6_ADDRSTRLEN);

				// 转换为CIDR前缀长度（如64）
				int prefix_len = ipv6_netmask_to_prefix(netmaskBuffer);
				if (prefix_len >= 0)
				{
					sprintf(result[count].netmask, "%d", prefix_len); // 存储为"64"而非子网掩码格式
				}
			}
			count++;
		}

	}

	if (ifAddrStruct != NULL)
	{
		freeifaddrs(ifAddrStruct);
	}
	// printf("count %d\n", count);
	return count;
}

static int _4gPopenCmd(int type, char* cmd, char* result)
{
	int flag = 0;
	int ret = 0;
	FILE* fp = NULL;
	char buf[255] = { 0 };
	if ((fp = popen(cmd, "r")) == NULL)
	{
		dzlog_info("_4gPopenCmd start popen error");
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (type == 0)
		{
			if (flag++ < 1)
			{
				continue;
			}
			if (strlen(buf) < 3)
			{
				continue;
			}
			char* ret = strstr(buf, "ERROR");
			if (ret != NULL)
			{
				ret = -1;
				break;
			}
			strcpy(result, buf);
			break;
		}
	}
	pclose(fp);
	return ret;
}

// 添加ppp无线网卡计数函数
int countPppInterfaces()
{
	FILE* fp;
	char buf[256];
	int count = 0;
	const char* cmd = "ifconfig";

	fp = popen(cmd, "r");
	if (fp == NULL)
	{
		dzlog_error("Failed to execute ifconfig command");
		return -1;
	}

	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		// 提取接口名称（以空格、冒号或制表符分隔）
		char* iface = strtok(buf, " :\t");
		if (iface == NULL) continue;

		// 检查是否为ppp0/ppp1/ppp2格式
		if (strncmp(iface, "ppp", 3) == 0 && strlen(iface) == 4)
		{
			char num = iface[3];
			if (num >= '0' && num <= '2')  // 只统计ppp0-ppp2
			{
				count++;
				dzlog_info("Found ppp interface: %s", iface);
			}
		}
	}

	pclose(fp);
	return count;
}

int _4gModules(PS_4GModule result)
{
	dzlog_info("_4gModules start");
	// dzlog_info("_4gModules start");
	if (!result)
	{
		return -1;
	}
	pthread_mutex_lock(&mutex);
	char result2[128] = { 0 };
	int wirelessConut = 0;
	wirelessConut = countPppInterfaces();
	dzlog_info("Found ppp interface1: %d", wirelessConut);
	if (wirelessConut == 0)
	{
		wirelessConut = 1;
	}

	for (int i = 0; i < wirelessConut; i++)
	{
		char pppDev[16] = { 0 };
		sprintf(pppDev, "ppp%d", i);  // 动态生成设备名：ppp0、ppp1...
		dzlog_info("Processing %s interface", pppDev);
		memset(result[i].iface, 0, 255);
		memcpy(result[i].iface, pppDev, 5);
		char cmd[64] = { 0 };
		sprintf(cmd, "wwan at send AT+CGMI dev %s", pppDev);  // 使用动态设备名
		int ret = _4gPopenCmd(0, cmd, result2);
		if (ret >= 0)
		{
			char* p2 = strstr(result2, "\r\n");
			if (p2)
			{
				memset(result[i].manufacture, 0, 32);
				memcpy(result[i].manufacture, result2, p2 - result2);
				dzlog_info("_4gModules start 2 result[i].manufacture[%s]", result[i].manufacture);
			}
			else
			{
				char* p2_tmp = strstr(result2, "\n");
				if(p2_tmp)
				{
					memset(result[i].manufacture, 0, 32);
					memcpy(result[i].manufacture, result2, p2_tmp - result2);
					dzlog_info("_4gModules start 2 result[i].manufacture[%s]", result[i].manufacture);
				}
			}
		}
		memset(result2, 0, 128);
		ret = _4gPopenCmd(0, "wwan at send AT+GMM dev ppp0", result2);
		if (ret >= 0)
		{
			dzlog_info("_4gModules start 3 result2[%s]", result2);
			char* p2 = strstr(result2, "\r\n");
			if (p2)
			{
				memset(result[i].model, 0, 32);
				memcpy(result[i].model, result2, p2 - result2);
				dzlog_info("_4gModules start 4 result[i].model[%s]", result[i].model);
			}
			else
			{
				p2 = strstr(result2, "\n");
				if (p2)
				{
					memset(result[i].model, 0, 32);
					memcpy(result[i].model, result2, p2 - result2);
					dzlog_info("_4gModules start 4 result[i].model[%s]", result[i].model);
				}
			}
		}
		memset(result2, 0, 128);
		ret = _4gPopenCmd(0, "wwan at send AT+CIMI dev ppp0", result2);
		if (ret >= 0)
		{
			dzlog_info("_4gModules start 5 result2[%s]", result2);
			char* p2 = strstr(result2, "\r\n");
			if (p2)
			{
				memset(result[i].imsi, 0, sizeof(result[i].imsi));
				memcpy(result[i].imsi, result2, p2 - result2);
				dzlog_info("_4gModules start 6 result[i].imsi[%s]", result[i].imsi);
			}
			else
			{
				p2 = strstr(result2, "\n");
				if (p2)
				{
					memset(result[i].imsi, 0, sizeof(result[i].imsi));
					memcpy(result[i].imsi, result2, p2 - result2);
					dzlog_info("_4gModules start 6 result[i].imsi[%s]", result[i].imsi);
				}
			}
		}
		memset(result2, 0, 128);
		ret = _4gPopenCmd(0, "wwan at send AT+QCCID dev ppp0", result2);
		dzlog_info("_4gModules start 7 ret[%d],result2[%s]", ret, result2);
		if (ret >= 0)
		{
			char* p = strstr(result2, "+QCCID: ");
			if (p)
			{
				p += strlen("+QCCID: ");
				char* p2 = strstr(p + 1, "\r\n");
				if (p2)
				{
					memset(result[i].simId, 0, 32);
					memcpy(result[i].simId, p, p2 - p);
					dzlog_info("_4gModules start 8 result[i].simId[%s]", result[i].simId);
				}
				else
				{
					p2 = strstr(p + 1, "\n");
					if (p2)
					{
						memset(result[i].simId, 0, 32);
						memcpy(result[i].simId, p, p2 - p);
						dzlog_info("_4gModules start 8 result[i].simId[%s]", result[i].simId);
					}
				}
			}
		}
		memset(result2, 0, 128);
		ret = _4gPopenCmd(0, "wwan at send AT+COPS? dev ppp0", result2);
		if (ret >= 0)
		{
			char* p = strstr(result2, "+COPS: 0,0,\"");
			if (p)
			{
				p += strlen("+COPS: 0,0,\"");
				char* p2 = strstr(p + 1, "\"");
				if (p2)
				{
					memset(result[i].carrierInformation, 0, 32);
					memcpy(result[i].carrierInformation, p, p2 - p);
					dzlog_info("_4gModules start 10 result[i].carrierInformation[%s]", result[i].carrierInformation);
				}
			}
			else
			{
				p = strstr(result2, "+COPS: 0, 0,\"");
				if (p)
				{
					p += strlen("+COPS: 0,0,\"");
					char* p2 = strstr(p + 1, "\"");
					if (p2)
					{
						memset(result[i].carrierInformation, 0, 32);
						memcpy(result[i].carrierInformation, p, p2 - p);
						dzlog_info("_4gModules start 10 result[i].carrierInformation[%s]", result[i].carrierInformation);
					}
				}
			}
		}
		memset(result2, 0, 128);

		ret = _4gPopenCmd(0, "wwan at send AT+CGPADDR dev ppp0", result2);
		dzlog_info("_4gModules start 11 ret[%d],result2[%s]", ret, result2);
		if (ret >= 0)
		{
			char* p = strstr(result2, "+CGPADDR: 1,");
			if (p)
			{
				p += strlen("+CGPADDR: 1,");
				p += 1;
				char* p2 = strstr(p + 1, "\"");
				if (p2)
				{
					memset(result[i].ip, 0, 32);
					memcpy(result[i].ip, p, p2 - p);
					dzlog_info("_4gModules start 12 result[i].ip[%s]", result[i].ip);
				}
			}
			else
			{
				p = strstr(result2, "+CGPADDR:1,");
				if (p)
				{
					dzlog_info("_4gModules start 113");
					p += strlen("+CGPADDR:1,");
					p += 1;
					char* p2 = strstr(p + 1, "\"");
					if (p2)
					{
						memset(result[i].ip, 0, 32);
						memcpy(result[i].ip, p, p2 - p);
						dzlog_info("_4gModules start 12 result[i].ip[%s]", result[i].ip);
					}
				}
			}
		}
		result[i].bandWidth = -1;
		memset(result2, 0, 128);
		ret = _4gPopenCmd(0, "wwan at send AT+QNWINFO dev ppp0", result2);
		(result2[strlen(result2) - 1] == '\n') && (result2[strlen(result2) - 1] = '\0');
		if (ret >= 0)
		{
			dzlog_info("_4gModules start 13 result2[%s]", result2);
			char* p = strstr(result2, "+QNWINFO: ");
			if (p)
			{
				p += strlen("+QNWINFO: ");
				p += 1;
				char* p2 = strstr(p + 1, ",");
				if (p2)
				{
					p2 -= 1;
					memset(result[i].netType, 0, 32);
					memcpy(result[i].netType, p, p2 - p);
					dzlog_info("_4gModules start 14 result[i].netType[%s]", result[i].netType);
				}
			}
		}
	}

	pthread_mutex_unlock(&mutex);
	return 0;
}


int reBoot(int relayTime, char* result)
{
	if (!result)
	{
		return -1;
	}
	sleep(relayTime);
	int ret = system("reboot");
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}

int syncNtp(char* ip, char* result)
{
	if (!result)
	{
		return -1;
	}
	char cmd[128] = { 0 };
	sprintf(cmd, "ntpdate %s", ip);
	int ret = popenCmd(cmd, result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int syncTime(char* timec, char* result)
{
	if (!result)
	{
		return -1;
	}
	char temp[64] = { 0 };
	char* p = strstr(timec, "T");
	if (p)
	{
		*p = ' ';
	}
	p = strstr(timec, "Z");
	if (p)
	{
		*p = ' ';
	}
	char* p2 = strstr(timec, "+08:00");
	if (p2)
	{
		memcpy(temp, timec, p2 - timec);
	}
	p2 = strstr(timec, "+8:00");
	if (p2)
	{
		memcpy(temp, timec, p2 - timec);
	}
	char cmd[128] = { 0 };
	// sprintf(cmd, "date -s \"%s\"", temp);
	// dzlog_info("syncTime cmd [%s]", cmd);
	// int ret = popenCmd(cmd, result);
	// (result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	// 解析时间字符串
	struct tm tm_time;
	struct timeval tv;
	memset(&tm_time, 0, sizeof(tm_time));
	strptime(temp, "%Y-%m-%d %H:%M:%S", &tm_time);
	// 将新的时间转换为时间戳
	tv.tv_sec = mktime(&tm_time); // 秒数
	tv.tv_usec = 0;				  // 微秒数

	int ret = settimeofday(&tv, NULL);
	//  设置系统时间
	if (ret == -1)
	{
		dzlog_error("Error setting system time\n");
	}
	return ret;
}

int systemDate4(char* result)
{
	if (!result)
	{
		return -1;
	}
	struct timeval tv;
	gettimeofday(&tv, NULL); // 获取当前时间，包括秒和微秒

	// 获取当前时间的秒数和微秒数
	time_t now = tv.tv_sec;
	suseconds_t milliseconds = tv.tv_usec / 1000; // 转换微秒为毫秒

	// 转换为本地时间
	struct tm* local = localtime(&now);
	sprintf(result, "%04d-%02d-%02dT%02d:%02d:%02d.%03ldZ",
		local->tm_year + 1900,
		local->tm_mon + 1,
		local->tm_mday,
		local->tm_hour,
		local->tm_min,
		local->tm_sec,
		milliseconds);
	return 0;
}

int systemDate3(char* result)
{
	if (!result)
	{
		return -1;
	}

	// int ret = popenCmd("echo \`date +%s%3N\`", result);
	//(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long time_in_mill =
		(tv.tv_sec) * 1000 +
		(tv.tv_usec) / 1000; // 秒转毫秒 + 微秒转毫秒
	// printf("Current time : %ld milliseconds\n", time_in_mill);
	sprintf(result, "%ld", time_in_mill);
	return 0;
}
int systemDate2(char* result)
{
	if (!result)
	{
		return -1;
	}

	int ret = popenCmd("echo \`date +%Y-%m-%dT%H:%M:%SZ\`", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int systemDate(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("echo \`date +%Y-%m-%dT%H:%M:%S+8:00\`", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}
int cpuTemp(char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = popenCmd("cat /sys/class/thermal/thermal_zone0/temp | awk  \'{printf \"%3.1f°C\",$1/1000}\'", result);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return ret;
}

int cpuUsed(char* result)
{
	if (!result)
	{
		return -1;
	}
	CPU_OCCUPY cpu_stat1;
	CPU_OCCUPY cpu_stat2;

	float cpu;
	// 第一次获取cpu使用情况
	get_cpuoccupy((CPU_OCCUPY*)&cpu_stat1);
	sleep(5);
	// 第二次获取cpu使用情况
	get_cpuoccupy((CPU_OCCUPY*)&cpu_stat2);
	// 计算cpu使用率
	cpu = cal_cpuoccupy((CPU_OCCUPY*)&cpu_stat1, (CPU_OCCUPY*)&cpu_stat2);
	sprintf(result, "%.2f%%", cpu);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return 0;
}

int cpuUsed_b(char* result)
{
	if (!result)
	{
		return -1;
	}
	CPU_OCCUPY cpu_stat1;
	CPU_OCCUPY cpu_stat2;

	float cpu;
	// 第一次获取cpu使用情况
	get_cpuoccupy((CPU_OCCUPY*)&cpu_stat1);
	sleep(2);
	// 第二次获取cpu使用情况
	get_cpuoccupy((CPU_OCCUPY*)&cpu_stat2);
	// 计算cpu使用率
	cpu = cal_cpuoccupy((CPU_OCCUPY*)&cpu_stat1, (CPU_OCCUPY*)&cpu_stat2);
	if (cpu <= 0)
	{
		cpu = 0.5;
	}
	sprintf(result, "%.2f", cpu);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return 0;
}

int memUsed(char* result)
{
	if (!result)
	{
		return -1;
	}
	MEM_OCCUPY mem_stat;
	float mem;
	// 获取内存
	mem = get_memoccupy((MEM_OCCUPY*)&mem_stat);
	// printf("内存使用率为：%.2f%%\n", mem);
	sprintf(result, "%.2f%%", mem);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return 0;
}

int diskUsed(char* result)
{
	if (!result)
	{
		return -1;
	}

	double disk;
	// 获取内存
	disk = get_sysDiskUsage();
	// printf("磁盘使用率为：%.2lf%%\n", disk);
	sprintf(result, "%.2lf%%", disk);
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
	return 0;
}
int rxBytes(char* eth, char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = 0;
	char line[256];
	int found = 0;

	char cmd[128] = { 0 };
	sprintf(cmd, "ifconfig %s | awk \'NR==8{printf $2}\'", eth);
	ret = popenCmd(cmd, result);
	char* p = strstr(result, ":");
	p && (strcpy(result, ++p));
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	return ret;
}
int txBytes(char* eth, char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = 0;

	char cmd[128] = { 0 };
	sprintf(cmd, "ifconfig %s | awk \'NR==8{printf $6}\'", eth);
	ret = popenCmd(cmd, result);
	char* p = strstr(result, ":");
	p && (strcpy(result, ++p));
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	return ret;
}
int rxPackets(char* eth, char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = 0;

	char cmd[128] = { 0 };
	sprintf(cmd, "ifconfig %s | awk \'NR==5{printf $2}\'", eth);
	ret = popenCmd(cmd, result);
	char* p = strstr(result, ":");
	p && (strcpy(result, ++p));
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	return ret;
}

int txPackets(char* eth, char* result)
{
	if (!result)
	{
		return -1;
	}
	int ret = 0;

	char cmd[128] = { 0 };
	sprintf(cmd, "ifconfig %s | awk \'NR==6{printf $2}\'", eth);
	ret = popenCmd(cmd, result);
	char* p = strstr(result, ":");
	p && (strcpy(result, ++p));
	(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');

	return ret;
}

int diskInfoReport(PS_DATA_REPORT_DISK result)
{
	char buf[256];

	int flag = 0;
	char* p[7] = { 0 };
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	if ((fp = popen("df -h", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag == 0)
		{
			flag = 1;
			continue;
		}
		// printf("%s", buf);
		p[0] = result->fileSystem;
		p[1] = result->size;
		p[2] = result->used;
		p[3] = result->available;
		p[4] = result->usedPercent;
		p[5] = result->mountedOn;
		p[6] = result->availablePercent;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			/* While there are tokens in "string" */
			// printf( "%s\n", token );
			if (i > 6)
			{
				break;
			}
			strcpy(p[i++], token);

			/* Get next token: */
			token = strtok(NULL, " ");
		}
		char buf[16] = { 0 };
		strcpy(buf, result->usedPercent);
		pStr = strstr(buf, "%");
		if (pStr)
		{
			*pStr = '\0';
			sprintf(p[i++], "%.f%%", 100 - atof(buf));
		}
		i = 0;
		char* p3 = strstr(result->mountedOn, "\n");
		if (p3)
		{
			*p3 = '\0';
		}
		result++;
		count++;
		if (count > 20)
			break;
	}
	pclose(fp);
	return count;
}

float getDisk_c2f(char* buf)
{
	char* p = NULL;
	p = strstr(buf, "M");
	if (p)
	{
		*p = '\0';
		return atof(buf);
	}
	else
	{
		p = strstr(buf, "G");
		if (p)
		{
			return atof(buf) * 1024;
		}
	}
	return 0;
}
int diskInfoReport2(PS_DATA_REPORT_DISK result, int count, PS_DATA_REPORT_DISK_SUM result2)
{
	int i = 0;

	float total = 0;
	float used = 0;
	float available = 0;

	for (; i < count; ++i)
	{

		total += getDisk_c2f(result->size);
		used += getDisk_c2f(result->used);
		available += getDisk_c2f(result->available);
		result++;
	}
	g_disk_total = total;
	sprintf(result2->total, "%.2fM", total);
	sprintf(result2->used, "%.2fM", used);
	sprintf(result2->available, "%.2fM", available);
	float free = total - used - available;
	sprintf(result2->free, "%.2fM", free);
	return count;
}
int _get4Gresult(char* cmd, char* b, char* e, char* result)
{
	int ret = popenCmd(cmd, result);
	char* p = strstr(cmd, b);
	if (p)
	{
		p += strlen(b);
		char* p2 = strstr(p, e);
		if (p2)
		{
			*p2 = '\0';
		}
		strcpy(result, ++p);
		(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		return 0;
	}
	return -1;
}

int _4GInfoReport2(PS_DATA_REPORT_4G result)
{
	/*
	if(access("/dev/ttyUSB2", 0) != 0)
	{
		return 0;
	}*/
	dzlog_info("_4GInfoReport2 1");

	char result2[1024] = { 0 };

	int ret1 = _4gPopenCmd(0, "wwan at send AT+QENG=\\\"servingcell\\\" dev ppp0", result2 /*, "AT+QENG"*/);
	if (ret1 >= 0)
	{
		char* p = strstr(result2, "+QENG: ");
		if (p)
		{
			int i = 0;
			p += strlen("+QENG: ");
			char* token = strtok(p, ",");
			while (token != NULL)
			{
				if (i == 10)
				{
					sprintf(result->upSpeed, "%s", token);
				}
				if (i == 11)
				{
					sprintf(result->downSpeed, "%s", token);
				}
				token = strtok(NULL, ",");
				i++;
			}
		}
	}
	memset(result2, 0, sizeof(result2));
	FILE* cmd = popen("wwan modem show dev ppp0", "r");
	if (cmd)
	{
		strcpy(result->sinr, "0");
	}

	while (fgets(result2, sizeof(result2), cmd) != NULL)
	{
		char* sinr = strstr(result2, "Current SINR:");
		if (sinr != NULL)
		{
			sinr = sinr + strlen("Current SINR:");
			// 跳过空格
			while (*sinr == ' ')
			{
				sinr++;
			}
			int i = 0;
			while (*sinr != 'd' && *sinr != ' ' && *sinr != '\0' && *sinr != '\n' && i < 9)
			{
				result->sinr[i++] = *sinr++;
			}
			result->sinr[i] = '\0';
		}

		char* rsrp = strstr(result2, "Current RSRP:");
		if (rsrp != NULL)
		{
			rsrp = rsrp + strlen("Current RSRP:");
			// 跳过空格
			while (*rsrp == ' ')
			{
				rsrp++;
			}
			int i = 0;
			while (*rsrp != 'd' && *rsrp != ' ' && *rsrp != '\0' && *rsrp != '\n' && i < 9)
			{
				result->rsrp[i++] = *rsrp++;
			}
			result->rsrp[i] = '\0';
		}

		char* rsrq = strstr(result2, "Current RSRQ:");
		if (rsrq != NULL)
		{
			rsrq = rsrq + strlen("Current RSRQ:");
			// 跳过空格
			while (*rsrq == ' ')
			{
				rsrq++;
			}
			int i = 0;
			while (*rsrq != 'd' && *rsrq != ' ' && *rsrq != '\0' && *rsrq != '\n' && i < 9)
			{
				result->rsrq[i++] = *rsrq++;
			}
			result->rsrq[i] = '\0';
		}

		char* rssi = strstr(result2, "Current RSSI:");
		if (rssi != NULL)
		{
			rssi = rssi + strlen("Current RSSI:");
			// 跳过空格
			while (*rssi == ' ')
			{
				rssi++;
			}
			int i = 0;
			while (*rssi != 'd' && *rssi != ' ' && *rssi != '\0' && *rssi != '\n' && i < 9)
			{
				result->rssi[i++] = *rssi++;
			}
			result->rssi[i] = '\0';
		}
	}
	pclose(cmd);
	// pthread_mutex_unlock(&mutex);
	return 1;

}

int _4GInfoReport(PS_DATA_REPORT_4G result)
{
	char buf[256];

	int flag = 0;
	FILE* fp = NULL;
	int count = 0;
	strcpy(result->iface, "ppp0");
	if ((fp = popen("ifconfig ppp0", "r")) == NULL)
	{
		dzlog_debug("ifconfig ppp0 error");
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		// printf("flag[%d] buf[%s]\n",flag,buf);

		// printf("%s", buf);
		if (flag == 3)
		{
			char* p = strstr(buf, "RX packets:");
			if (p)
			{
				p += strlen("RX packets:");
				char* p3 = strstr(p, " ");
				*p3 = '\0';
				result->rxPackets = atoi(p);
			}
		}
		else if (flag == 4)
		{
			char* p = strstr(buf, "TX packets:");
			if (p)
			{
				p += strlen("TX packets:");
				char* p3 = strstr(p, " ");
				*p3 = '\0';
				result->txPackets = atoi(p);
			}
		}
		else if (flag == 6)
		{
			char* p = strstr(buf, "RX bytes:");
			if (p)
			{
				p += strlen("RX bytes:");
				char* p3 = strstr(p, " ");
				*p3 = '\0';
				result->rxBytes = atoi(p);
				p = strstr(p3 + 1, "TX bytes:");
			}

			if (p)
			{
				p += strlen("TX bytes:");
				char* p3 = strstr(p, " ");
				*p3 = '\0';
				result->txBytes = atoi(p);
			}
		}

		flag++;
	}
	strcpy(result->iface, "ppp0");
	strcpy(result->rsrp, "-103");
	strcpy(result->rsrq, "-10");
	strcpy(result->rssi, "28");
	strcpy(result->sinr, "18");
	strcpy(result->upSpeed, "19");
	strcpy(result->downSpeed, "30");
	strcpy(result->speed, "1000");
	pclose(fp);

	return 1;
}

int netLink(char* result)
{
	int ret = 0;

	char net_uuid[64] = { 0 };
	GF_GetGUID(net_uuid);
	mqtt_send_net_test(net_uuid, 1, "device");
	ST_NETINFO netInfo;
	get_net_info(net_uuid, &netInfo, "device");
	sprintf(result, "%f", (float)netInfo.last);
	g_dataNetTtl = netInfo.ttl;

	return ret;
}
// 进程数据上报定义2

// 进程数据上报定义2
typedef struct _S_DATA_REPORT_PROCESS3
{
	char uid[16];
	char user[16];
	char gid[16];
	char group[16];
} S_DATA_REPORT_PROCESS3, * PS_DATA_REPORT_PROCESS3;

static int getMon(char* smon)
{
	if (strcmp("Jan", smon) == 0)
	{
		return 1;
	}
	else if (strcmp("Feb", smon) == 0)
	{
		return 2;
	}
	else if (strcmp("Mar", smon) == 0)
	{
		return 3;
	}
	else if (strcmp("Apr", smon) == 0)
	{
		return 4;
	}
	else if (strcmp("May", smon) == 0)
	{
		return 5;
	}
	else if (strcmp("Jun", smon) == 0)
	{
		return 6;
	}
	else if (strcmp("Jul", smon) == 0)
	{
		return 7;
	}
	else if (strcmp("Aug", smon) == 0)
	{
		return 8;
	}
	else if (strcmp("Sep", smon) == 0)
	{
		return 9;
	}
	else if (strcmp("Oct", smon) == 0)
	{
		return 10;
	}
	else if (strcmp("Nov", smon) == 0)
	{
		return 11;
	}
	else if (strcmp("Dec", smon) == 0)
	{
		return 12;
	}
	else
	{
		return 1;
	}
}
static int propcessInfoReport6(PS_DATA_REPORT_PROCESS result, int countR)
{
	// 该started字段为时间字段，读取格式异常导致后端落库时卡死，暂先置为空
	int ii = 0;
	for (; ii < countR; ++ii)
	{
		memset(result->started, 0, 32);
	}
	return countR;

	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	char cmd[255] = { 0 };
	char buf[1024] = { 0 };
	int j = 0;
	for (; j < countR; ++j)
	{
		i = 0;
		sprintf(cmd, "ps -p %s -o lstart", result->pid);
		if ((fp = popen(cmd, "r")) == NULL)
		{
			pclose(fp);
			dzlog_error("propcessInfoReport6 popen cmd[%s] faile", cmd);
			return -1;
		}
		while (fgets(buf, 1024, fp) != NULL)
		{
			if (0 == i++)
				continue;
			(buf[strlen(buf) - 1] == '\n') && (buf[strlen(buf) - 1] = '\0');
			// printf("propcessInfoReport6 buf[%s]\n",buf);
			/*Wed Sep  4 22:49:48 2024*/
			char* token = strtok(buf, " ");
			int k = 0;
			char bufmon[16] = { 0 };
			char bufday[16] = { 0 };
			char bufhms[16] = { 0 };
			char bufyear[16] = { 0 };
			while (token != NULL)
			{
				/* Get next token: */
				if (k == 1)
				{
					int imon = getMon(token);
					sprintf(bufmon, "%d", imon);
					// printf("propcessInfoReport6 imon[%d] ,bufmon[%s]\n",imon,bufmon);
				}
				else if (k == 2)
				{
					strcpy(bufday, token);
				}
				else if (k == 3)
				{
					strcpy(bufhms, token);
				}
				else if (k == 4)
				{
					strcpy(bufyear, token);
				}
				// printf("propcessInfoReport6 k[%d] ,token[%s]\n",k,token);
				token = strtok(NULL, " ");
				k++;
			}

			sprintf(result->started, "%s-%s-%s %s", bufyear, bufmon, bufday, bufhms);
			// printf("propcessInfoReport6 result->started[%s]\n",result->started);
		}
		result++;
		pclose(fp);
	}
	return countR;
}
static int propcessInfoReport5(PS_DATA_REPORT_PROCESS result, int countR, PS_DATA_REPORT_PROCESS_EVENT result2)
{
	S_DATA_REPORT_PROCESS2 top[50] = { 0 };
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	int count2 = 0;
	char* pStr = NULL;
	char buf[255] = { 0 };
	int flag999 = 0;
	if ((fp = popen("top -n 1 -b", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag < 4)
		{
			flag++;
			continue;
		}
		if (flag999 == 0)
		{
			char* p = strstr(buf, "PID USER");
			if (!p)
			{
				continue;
			}
			else
			{
				flag999 = 1;
				continue;
			}
		}


		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			/* While there are tokens in "string" */
			// printf( "%s\n", token );
			if (i >= 8)
			{
				// break;
			}
			if (i == 0)
			{
				if (*token == 27)
				{
					token = strtok(NULL, " ");
					continue;
				}
				strcpy(top[count].pid, token);
			}
			if (i == 0)
				strcpy(top[count].pid, token);
			if (i == 8)
				strcpy(top[count].cpuUsage, token);
			if (i == 9)
				strcpy(top[count].memUsage, token);
			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}

		i = 0;
		count++;
		if (count >= 50)
		{
			break;
		}
	}
	pclose(fp);
	int j = 0;
	int k = 0;
	int flag2 = 0;
	for (k = 0; k < countR; ++k)
	{
		flag2 = 0;
		for (j = 0; j < count; ++j)
		{
			if (strcmp(result->pid, top[j].pid) == 0)
			{
				if (atof(top[j].cpuUsage) > 0.0 || atof(top[j].memUsage) > 0.0)
				{
					flag2 = 1;
					strcpy(result->cpuUsage, top[j].cpuUsage);
					strcpy(result->memUsage, top[j].memUsage);
					break;
				}
			}
		}

		if (flag2 == 1)
		{
			strcpy(result2->eventType, "updateProcess");
			result2->isFull = 1;

			memcpy(&result2->process, result, sizeof(S_DATA_REPORT_PROCESS));

			result2++;
			count2++;
		}

		result++;
	}
	return count2;
}
static int propcessInfoReport4(PS_DATA_REPORT_PROCESS result, int countR)
{
	// S_DATA_REPORT_PROCESS3 user[50] = {0};
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	char cmd[255] = { 0 };
	char buf[1024] = { 0 };
	char buf2[255] = { 0 };
	int j = 0;
	for (; j < countR; ++j)
	{
		char dir[128] = { 0 };
		char md5[128] = { 0 };
		struct stat st = { 0 };
		sprintf(dir, "/proc/%s/exe", result->pid);
		if (stat(dir, &st) != -1)
		{
			memset(md5, 0, strlen(md5));
			calculate_md5(dir, md5);
			strcpy(result->procMd5, md5);
		}
		memset(dir, 0, strlen(dir));
		sprintf(dir, "/proc/%s/stat", result->pid);
		if (stat(dir, &st) == -1)
		{
			result++;
			continue;
		}
		sprintf(cmd, "head /proc/%s/stat", result->pid);
		if ((fp = popen(cmd, "r")) == NULL)
		{
			pclose(fp);
			dzlog_error("propcessInfoReport4 popen cmd[%s] faile", cmd);
			return -1;
		}
		while (fgets(buf, 1024, fp) != NULL)
		{
			i = 0;
			char* token = strtok(buf, " ");
			while (token != NULL)
			{
				if (i >= 4)
				{
					break;
				}
				if (i == 1)
				{
					strcpy(buf2, token);
					char* p = strstr(buf2, ")");
					if (p)
					{
						*p = '\0';
						strcpy(result->pName, &buf2[1]);
						// //dzlog_info("propcessInfoReport4 result->pName[%s]\n", result->pName);
					}
					else
					{
						// printf("00000000000000000000000000000000000000000000000000000000000000000 result->pid [%s]\n",result->pid);
					}
				}
				if (i == 2)
				{
					strcpy(result->state, token);
					if (result->state[0] == 'R')
					{
						strcpy(result->state, "Runnable");
					}
					else if (result->state[0] == 'S')
					{
						strcpy(result->state, "Sleeping");
					}
					else if (result->state[0] == 'T')
					{
						strcpy(result->state, "Stopped");
					}
					else if (result->state[0] == 'D')
					{
						strcpy(result->state, "UninterruptibleDiskSleep");
					}
					else if (result->state[0] == 'Z')
					{
						strcpy(result->state, "Zombie");
					}
					else
					{
						strcpy(result->state, "Idle");
					}
				}
				if (i == 3)
				{

					// strcpy(buf,token);
					strcpy(result->ppid, token);
					// //dzlog_info("propcessInfoReport4 result->ppid[%s]", token);
					break;
				}
				/* Get next token: */
				token = strtok(NULL, " ");
				i++;
			}
		}
		result++;
		pclose(fp);
	}
	return countR;
}

static int propcessInfoReport3(PS_DATA_REPORT_PROCESS result, int countR)
{
	S_DATA_REPORT_PROCESS3 user[50] = { 0 };
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	char buf[255] = { 0 };
	if ((fp = popen("cat /etc/passwd | cut -d : -f1,3,4,5", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* token = strtok(buf, ":");
		while (token != NULL)
		{
			if (i >= 4)
			{
				break;
			}
			char* p3 = strstr(token, "\n");
			if (p3)
			{
				*p3 = '\0';
			}

			if (i == 0)
				strcpy(user[count].user, token);
			if (i == 1)
				strcpy(user[count].uid, token);
			if (i == 2)
				strcpy(user[count].gid, token);
			if (i == 3)
				strcpy(user[count].group, token);

			/* Get next token: */
			token = strtok(NULL, ":");
			i++;
		}

		i = 0;
		count++;
		if (count >= 50)
		{
			break;
		}
	}
	pclose(fp);
	int j = 0;
	int k = 0;
	for (; j < countR; ++j)
	{
		for (k = 0; k < count; ++k)
		{
			if (strcmp(result->user, user[k].user) == 0)
			{
				strcpy(result->uid, user[k].uid);
				strcpy(result->user, user[k].user);
				strcpy(result->gid, user[k].gid);
				strcpy(result->group, user[k].group);
			}
		}
		result++;
	}
	return countR;
}

static int propcessInfoReport2(PS_DATA_REPORT_PROCESS result, int countR)
{
	S_DATA_REPORT_PROCESS2 top[100] = { 0 };
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	char buf[255] = { 0 };
	int flag2 = 0;
	if ((fp = popen("top -n 1 -b -o %MEM", "r")) == NULL)
	{
		dzlog_error("propcessInfoReport2 top -n 1 error");
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag < 4)
		{
			flag++;
			continue;
		}
		if (flag2 == 0)
		{
			char* p = strstr(buf, "PID USER");
			if (!p)
			{

				continue;
			}
			else
			{
				flag2 = 1;
				continue;
			}
		}


		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i == 0)
			{
				if (*token == 27)
				{
					token = strtok(NULL, " ");
					continue;
				}
				strcpy(top[count].pid, token);
			}
			if (i == 0)
			{
				strcpy(top[count].pid, token);
			}
			if (i == 7)
			{
				strcpy(top[count].status, token);

			}
			if (i == 8)
			{
				strcpy(top[count].cpuUsage, token);
			}
			if (i == 9)
			{
				strcpy(top[count].memUsage, token);
			}


			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}

		i = 0;
		count++;
		if (count >= 100)
		{
			break;
		}
		usleep(1000);
	}
	pclose(fp);
	int j = 0;
	int k = 0;
	for (; j < countR; ++j)
	{
		char* baseUsage = "0.0";
		strcpy(result->cpuUsage, baseUsage);
		strcpy(result->memUsage, baseUsage);
		for (k = 0; k < count; ++k)
		{
			if (strcmp(result->pid, top[k].pid) == 0)
			{
				if (top[k].status[0] == 'R')
				{
					strcpy(result->state, "Runnable");
				}
				else if (top[k].status[0] == 'S')
				{
					strcpy(result->state, "Sleeping");
				}
				else if (top[k].status[0] == 'T')
				{
					strcpy(result->state, "Stopped");
				}
				else if (top[k].status[0] == 'D')
				{
					strcpy(result->state, "UninterruptibleDiskSleep");
				}
				else if (top[k].status[0] == 'Z')
				{
					strcpy(result->state, "Zombie");
				}
				else
				{
					strcpy(result->state, "Idle");
				}
				// printf("******************************* top[%d].cpuUsage[%s],top[%d].memUsage[%s]\n", k, top[k].cpuUsage, k, top[k].memUsage);
				if (strcmp(top[k].cpuUsage, baseUsage) == 0 && strcmp(top[k].memUsage, baseUsage) == 0)
				{
					break;
				}
				strcpy(result->cpuUsage, top[k].cpuUsage);
				strcpy(result->memUsage, top[k].memUsage);

				break;
			}
		}
		result++;
	}
	return countR;
}

int canConvertToNumber(const char* str)
{
	char* endptr;
	errno = 0;				  // 重置errno
	strtol(str, &endptr, 10); // 尝试将字符串转换为长整型数

	// 检查转换是否成功以及是否还有剩余字符
	if (errno == ERANGE || *endptr != '\0' || (str == endptr))
	{
		return 0; // 转换失败
	}
	return 1; // 转换成功
}

int propcessInfoReport0(PS_DATA_REPORT_PROCESS result)
{
	char buf[1024];
	int flag = 0;
	char* p[7] = { 0 };
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	int abandon = 0;
	char* pStr = NULL;
	if ((fp = popen("ps -ef", "r")) == NULL)
	{
		dzlog_error("propcessInfoReport0 popen error");
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 1024, fp) != NULL)
	{
		if (flag == 0)
		{
			flag = 1;
			continue;
		}
		p[0] = result->pid;
		p[1] = result->user;

		p[3] = result->state;
		p[4] = result->cmd;
		///
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i >= 8)
			{
				break;
			}
			if (i == 0)
			{
				strcpy(result->user, token);
			}
			else if (i == 1)
			{
				if (canConvertToNumber(token) != 1) // 用fgets循环取时，当某一行数据字符超过255，则下一次循环并不是直接读下一行到buf，而是读该行的剩余部分到buf
				{
					abandon = 1;
					break;
				}
				strcpy(result->pid, token);
			}
			else if (i == 7)
			{
				strcpy(result->cmd, token);
			}
			i++;
			/* Get next token: */
			token = strtok(NULL, " ");
		}
		token = NULL;
		i = 0;
		if (abandon == 1)
		{
			continue;
		}
		char* p3 = strstr(result->cmd, "\n");
		if (p3)
		{
			*p3 = '\0';
		}

		/*if (result->state[0] == 'R')
		{
			strcpy(result->state, "Runnable");
		}
		else if (result->state[0] == 'S')
		{
			strcpy(result->state, "Sleeping");
		}
		else if (result->state[0] == 'T')
		{
			strcpy(result->state, "Stopped");
		}
		else if (result->state[0] == 'D')
		{
			strcpy(result->state, "UninterruptibleDiskSleep");
		}
		else if (result->state[0] == 'Z')
		{
			strcpy(result->state, "Zombie");
		}
		else
		{
			strcpy(result->state, "Idle");
		}*/
		result++;
		count++;
		// if (count >= 330)
		// 过多数据会挂掉，先设定50
		if (count >= 330)
			break;

		memset(buf, 0, 1024);
	}
	pclose(fp);
	return count;
}
/// docker

static int containerInfoReport5(PS_DATA_REPORT_CONTAINER_EVENT result, int count)
{
	int count2 = 0;
	char* pStr = NULL;

	int j = 0;
	for (; j < count; ++j)
	{
		CONTAINER_INFO container = { 0 };

		int ret = SqlSearchContainerid(&container, result->name);
		dzlog_info("containerInfoReport5 result->name[%s] ret[%d]", result->name, ret);
		if (ret == 0)
		{
			strcpy(result->type, container.type);
			strcpy(result->containerId, container.containerid);
			strcpy(result->id, container.id);

			dzlog_info("containerInfoReport5 result->name[%s]", result->name);

			if (strlen(result->type) <= 0)
			{
				strcpy(result->type, "docker");
			}

			if (strlen(result->containerId) <= 0 || strlen(result->id) <= 0)
			{
				dzlog_info("containerInfoReport5 result->name[%s]", result->name);

				char cmd[128] = { 0 };
				sprintf(cmd, "docker inspect --format='{{.Id}}' %s", result->name);
				FILE* fp = popen(cmd, "r");
				if (fp)
				{
					char id[65];
					fgets(id, 65, fp);
					pclose(fp);
					if (strlen(id) > 0)
					{
						strcpy(result->containerId, id);
						strncpy(result->id, id, 12);
						dzlog_info("containerInfoReport5 result->name[%s]", result->name);

						dzlog_info("containerInfoReport5 result->containerId[%s]", result->containerId);
						IOTA_CONTAINER_INFO container_info = { 0 };
						container_info.containerHyperv = result->type;
						container_info.containerId = result->containerId;
						container_info.containerName = result->name;

						container_sql_insert(container_info, result->id);

						dzlog_info("containerInfoReport5 result->name[%s]", result->name);
					}
				}
			}
		}
		result++;
		count2++;
	}
	return count;
}

// static int containerInfoReport4(PS_DATA_REPORT_CONTAINER_EVENT result, int count)
//{
//	char buf[1024];
//	int flag = 0;
//	int i = 0;
//	FILE *fp = NULL;
//	int count2 = 0;
//	char *pStr = NULL;
//	int diskUse = 0;
//	if ((fp = popen("docker system df", "r")) == NULL)
//	{
//		pclose(fp);
//		return -1;
//	}
//	while (fgets(buf, 1024, fp) != NULL)
//	{
//		if (flag == 0)
//		{
//			flag = 1;
//			continue;
//		}
//		char *token = strtok(buf, " ");
//		while (token != NULL)
//		{
//			if (i == 3)
//			{
//				diskUse = atoi(token);
//			}
//
//			/* Get next token: */
//			token = strtok(NULL, " ");
//		}
//		break;
//	}
//	pclose(fp);
//	int j = 0;
//	char cdisk[32] = {0};
//	int ret = diskUsed(cdisk);
//	if (ret < 0)
//	{
//		return -1;
//	}
//	float fdisk = (float)diskUse / atoi(cdisk);
//	fdisk /= 100;
//	diskUse = (int)fdisk;
//	for (; j < count; ++j)
//	{
//		result->diskUsed = diskUse;
//		result++;
//		count2++;
//	}
//	return count;
// }

static int containerInfoReport4(PS_DATA_REPORT_CONTAINER_EVENT result, int count)
{
	char buf[1024];
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count2 = 0;
	char* pStr = NULL;
	int diskUse = 0;
	if ((fp = popen("docker system df", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 1024, fp) != NULL)
	{
		if (flag == 0)
		{
			flag = 1;
			continue;
		}
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i == 3)
			{
				diskUse = atoi(token);
			}

			/* Get next token: */
			token = strtok(NULL, " ");
		}
		break;
	}
	pclose(fp);
	int j = 0;
	char cdisk[32] = { 0 };
	int ret = diskUsed(cdisk);
	if (ret < 0)
	{
		return -1;
	}
	float fdisk = (float)diskUse / atoi(cdisk);
	fdisk /= 100;
	diskUse = (int)fdisk;
	for (; j < count; ++j)
	{
		result->diskUsed = diskUse;
		result++;
		count2++;
	}
	return count;
}

static int containerInfoReport3(PS_DATA_REPORT_CONTAINER_EVENT result, int count)
{
	char buf[256];
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	char cmd[64] = { 0 };
	int j = 0;
	int count2 = 0;
	int size[9] = { 0 };
	for (j = 0; j < count; j++)
	{
		sprintf(cmd, "docker stats --no-stream %s", result->id);
		if ((fp = popen(cmd, "r")) == NULL)
		{
			pclose(fp);
			return -1;
		}
		while (fgets(buf, 255, fp) != NULL)
		{
			if (flag == 0)
			{
				// CONTAINER ID   NAME        CPU% MEM USAGE / LIMIT   MEM % NET I / O       BLOCK I / O         PIDS
				// 获取每个字段的长度
				char* p0 = strstr(buf, "CONTAINER ID");
				char* p1 = strstr(buf, "NAME");
				char* p2 = strstr(buf, "CPU %");
				char* p3 = strstr(buf, "MEM USAGE / LIMIT");
				char* p4 = strstr(buf, "MEM %");
				char* p5 = strstr(buf, "NET I/O");
				char* p6 = strstr(buf, "BLOCK I/O");
				char* p7 = strstr(buf, "PIDS");
				char* p8 = strstr(buf, "\n");
				size[0] = p1 - p0;
				size[1] = p2 - p1;
				size[2] = p3 - p2;
				size[3] = p4 - p3;
				size[4] = p5 - p4;
				size[5] = p6 - p5;
				size[6] = p7 - p6;
				size[7] = p8 - p7;
				flag++;
				continue;
			}
			char temp[32] = { 0 };
			memset(temp, 0, 32);
			memcpy(temp, buf + size[0] + size[1] + size[2] + size[3], size[4] + 1);
			char* p = strstr(temp, "%");
			if (p)
			{
				*p = '\0';
			}
			result->memUsed = atof(temp);
			memset(temp, 0, 32);
			memcpy(temp, buf + size[0] + size[1], size[2] + 1);
			p = strstr(temp, "%");
			if (p)
			{
				*p = '\0';
			}
			result->cpuUsed = atof(temp);
			result++;
			count2++;
			break;
		}
		pclose(fp);
	}

	return count2;
}

static int containerInfoReport2(PS_DATA_REPORT_CONTAINER_EVENT result, int count)
{
	char buf[1024];
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count2 = 0;
	char* pStr = NULL;
	char cmd[64] = { 0 };
	char* p = NULL;
	int j = 0;
	for (; j < count; ++j)
	{
		sprintf(cmd, "docker inspect %s", result->name);
		if ((fp = popen(cmd, "r")) == NULL)
		{
			pclose(fp);
			return -1;
		}
		while (fgets(buf, 1024, fp) != NULL)
		{
			if (flag < 5)
			{
				p = strstr(buf, "\"Created\": \"");
				if (p)
				{
					char* p2 = strstr(buf, "\",\n");
					memset(result->deployTime, 0, 32);
					memcpy(result->deployTime, p + strlen("\"Created\": \""), p2 - p - strlen("\"Created\": \""));
				}
			}
			if (flag < 9 && flag > 5)
			{
				p = strstr(buf, "\"Status\": \"");
				if (p)
				{
					char* p2 = strstr(buf, "\",\n");
					memset(result->status, 0, 16);
					memcpy(result->status, p + strlen("\"Status\": \""), p2 - p - strlen("\"Status\": \""));
					break;
				}
			}
			flag++;
		}
		flag = 0;
		result++;
		count2++;
		pclose(fp);
	}

	return count2;
}

static int containerInfoReport0(PS_DATA_REPORT_CONTAINER_EVENT result)
{
	// CONTAINER ID        IMAGE						COMMAND             CREATED             STATUS              PORTS               NAMES
	// 226861c07275        wybase - img - test:arm64 "/bin/sh"           15 minutes ago      Created                                 test11

	char buf[1024];
	int size[8] = { 0 };
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	if ((fp = popen("docker ps -a --format \" {{.Names}} \"", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 1024, fp) != NULL)
	{
		buf[strlen(buf) - 1] = '\0';
		dzlog_info("containerInfoReport0 start buf[%s]", buf);
		strcpy(result->name, buf);
		// 	if (flag == 0)
		// 	{
		// 		flag = 1;
		// 		// 获取每个字段的长度
		// 		char *p0 = strstr(buf, "CONTAINER ID");
		// 		char *p1 = strstr(buf, "IMAGE");
		// 		char *p2 = strstr(buf, "COMMAND");
		// 		char *p3 = strstr(buf, "CREATED");
		// 		char *p4 = strstr(buf, "STATUS");
		// 		char *p5 = strstr(buf, "PORTS");
		// 		char *p6 = strstr(buf, "NAMES");
		// 		char *p7 = strstr(buf, "\n");
		// 		size[0] = p1 - p0;
		// 		size[1] = p2 - p1;
		// 		size[2] = p3 - p2;
		// 		size[3] = p4 - p3;
		// 		size[4] = p5 - p4;
		// 		size[5] = p6 - p5;
		// 		size[6] = p7 - p6;
		// 		continue;
		// 	}
		// 	char temp[1024] = {0};
		// 	memset(temp, 0, 1024);
		// 	memcpy(temp, buf + size[0] + size[1] + size[2] + size[3] + size[4] + size[5], strlen(buf) - size[0] - size[1] - size[2] - size[3] - size[4] - size[5] - 1);
		// 	strcpy(result->name, temp);
		// 	dzlog_info("containerInfoReport0 start name[%s]", temp);

		// 	// char image[64] = { 0 };
		// 	// char image_repository[32] = { 0 };
		// 	// char image_tag[32] = { 0 };
		// 	// memset(image, 0, 64);
		// 	// memcpy(image, buf + size[0], size[1] - 1);
		// 	// dzlog_info("containerInfoReport0 start image[%s]", image);
		// 	// char* token;                           // 用于存储每次分割的结果
		// 	// int i = 0;                             // 数组索引
		// 	// token = strtok(image, ":");
		// 	// while (token != NULL && i < 2) {
		// 	//	//result->image[i++] = token;
		// 	//	strcpy(result->image[i++], token);
		// 	//	token = strtok(NULL, ":");
		// 	// }
		// 	//// 打印分割结果
		// 	// for (int j = 0; j < i; j++) {
		// 	//	dzlog_info("containerInfoReport0 start result->image[%d][%s]", j, result->image[j++]);
		// 	// }

		result++;
		count++;
	}
	pclose(fp);
	return count;
}

unsigned long long generate_random_number()
{
	unsigned long long random_number = 0;
	int i;

	// 使用当前时间作为随机数生成器的种子
	// 这确保了每次运行程序时都会得到不同的随机数序列
	srand(time(NULL));
	random_number = 1;

	// 接下来的17位是0到9之间的数字
	for (i = 1; i < 18; i++)
	{
		random_number = random_number * 10 + rand() % 10;
	}

	return random_number;
}

///////////////
static int appInfoReport4(PS_DATA_REPORT_APP_EVENT result, int count)
{
	int count2 = 0;
	char* pStr = NULL;

	int j = 0;
	for (; j < count; ++j)
	{
		APP_INFO app = { 0 };

		int ret = SqlSearchAppid(&app, result->name);
		if (ret)
		{
			if (strlen(app.appid) != 0 && *app.appid != '\0')
			{
				strcpy(result->appId, app.appid);
				result->isTrustworthy = app.isTrustworthy;
				memset(result->name, 0, 128);
				strcpy(result->name, app.name);
				if (app.isTrustworthy == 1)
				{
					strcpy(result->version, app.appversion);
				}
			}
			else
			{
				unsigned long long ranom_number = generate_random_number();
				// printf("random num [%llu]", ranom_number);
				dzlog_info("111 random num [%llu]", ranom_number);
				sprintf(result->appId, "%llu", ranom_number);
				result->isTrustworthy = 0;
				IOTA_APP_ADD_NEEDINFO tmp = { 0 };
				tmp.appId = result->appId;
				tmp.appName = result->name;
				tmp.version = result->version;
				tmp.isTrustworthy = 0;
				bool reb = SqlAddAppInfo_V1(tmp);
				// new end
				sleep(1);
			}
		}
		else
		{
			unsigned long long ranom_number = generate_random_number();
			// printf("random num [%llu]", ranom_number);
			dzlog_info("222 random num [%llu]", ranom_number);
			sprintf(result->appId, "%llu", ranom_number);
			result->isTrustworthy = 0;
			IOTA_APP_ADD_NEEDINFO tmp = { 0 };
			tmp.appId = result->appId;
			tmp.appName = result->name;
			tmp.version = result->version;
			tmp.isTrustworthy = 0;
			bool reb = SqlAddAppInfo_V1(tmp);
			// new end
			sleep(1);
		}
		result++;
		count2++;
	}
	return count2;
}
static int appInfoReport3(PS_DATA_REPORT_APP_EVENT result, int count)
{

	char buf[256];
	int flag = 0;
	S_DATA_REPORT_APP_EVENT sappV[50] = { 0 };
	int i = 0;
	FILE* fp = NULL;
	int count2 = 0;
	char cmd[128] = { 0 };
	if ((fp = popen("appm -V", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		int iserr = 0;
		char* p = strstr(buf, "/");
		if (p)
		{
			iserr = 1;
		}
		i = 0;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{

			/* While there are tokens in "string" */
			if (i == 0)
			{
				strcpy(sappV[count2].name, token);
				if (iserr == 1)
				{
					break;
				}
			}
			else if (i == 1)
			{
				strcpy(sappV[count2].version, token);
			}
			else if (i == 2)
			{
				strcpy(sappV[count2].deployTime, token);
			}
			else if (i == 3)
			{
				char* p = strstr(token, "\n");
				if (p)
				{
					*p = '\0';
				}
				strcat(sappV[count2].deployTime, "T");
				strcat(sappV[count2].deployTime, token);
				strcat(sappV[count2].deployTime, "Z");
			}
			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
		count2++;
	}
	int j = 0;
	for (; j < count; j++)
	{
		for (i = 0; i < count2; ++i)
		{
			if (strcmp(result->name, sappV[i].name) == 0)
			{
				if (sappV[i].deployTime != NULL && strlen(sappV[i].deployTime) != 0)
				{
					strcpy(result->deployTime, sappV[i].deployTime);
					strcpy(result->version, sappV[i].version);
					//dzlog_info("11111 name[%s],version[%s]", result->name, result->version);
					break;
				}
				else
				{
					strcpy(result->deployTime, "2024-03-01T14:59:28Z");
					strcpy(result->version, "v1.0.0");
					break;
				}
			}
		}
		result++;
	}
	pclose(fp);
	return count;
}

int toGetDiskUsed(char* name, char* res)
{
	// dzlog_info("toGetDiskUsed start");
	char cmd[64] = { 0 };
	int isreturn = -1;
	FILE* fp = NULL;
	char buf[256];
	long Tnum = 0;
	long num1 = 0;
	long num2 = 0;
	int i = 0;
	sprintf(cmd, "df -k | awk \'{a+=$2}END{print a}\'");
	if ((fp = popen(cmd, "r")) == NULL)
	{
		// dzlog_info("toGetDiskUsed start 44");
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			char* endptr;
			Tnum = strtol(token, &endptr, 10);
			break;
		}
		break;
	}
	pclose(fp);

	sprintf(cmd, "du -sk /userdata/tmp/app/%s", name);
	if ((fp = popen(cmd, "r")) == NULL)
	{
		// dzlog_info("toGetDiskUsed start 66");
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			char* endptr;
			num1 = strtol(token, &endptr, 10);
			break;
		}
		break;
	}
	pclose(fp);

	// sprintf(cmd, "du -sk /userdata/tmp/log/%s* | awk \'{total += \$1} END {print total}\'", name);
	// if ((fp = popen(cmd, "r")) == NULL)
	//{
	//	//dzlog_info("toGetDiskUsed start 88");
	//	pclose(fp);
	//	return -1;
	// }
	// while (fgets(buf, 255, fp) != NULL)
	//{
	//	char* token = strtok(buf, " ");
	//	while (token != NULL)
	//	{
	//		char* endptr;
	//		num2 = strtol(token, &endptr, 10);
	//		break;
	//	}
	//	break;
	// }
	// pclose(fp);
	sprintf(res, "%f", ((double)num1 /*+ (double)num2 + 12.0*/) / (double)Tnum * 100);

	return 0;
}
static int appInfoReport2(PS_DATA_REPORT_APP_EVENT result, int count)
{
	// int flag = 0;
	// int i = 0;
	int j = 0;
	int count2 = 0;
	// char buf[256];
	char resnum[16] = { 0 };
	char rescpunum[16] = { 0 };
	char resdisknum[16] = { 0 };
	for (; j < count; ++j)
	{

		memset(resnum, 0, 16);
		memset(rescpunum, 0, 16);
		memset(resdisknum, 0, 16);
		if (result->pid == -1)
		{
			// dzlog_info("appname[%s] pid == -1", result->name);
			int res = toGetDiskUsed(result->name, resdisknum);
			//dzlog_info("toGetDiskUsed-2 res = %d resdisknum = %s", res, resdisknum);
			result->diskUsed = atof(resdisknum);
			count2++;
			result++;
			continue;
		}
		int res = get_process_memory_usage(result->pid, resnum);
		res = get_process_cpu_usage(result->pid, rescpunum);
		res = toGetDiskUsed(result->name, resdisknum);
		result->memUsed = atof(resnum);
		result->cpuUsed = atof(rescpunum);
		result->diskUsed = atof(resdisknum);
		result++;
		count2++;
	}
	return count2;
}
static int appInfoReport0(PS_DATA_REPORT_APP_EVENT result)
{
	char buf[256];
	int flag = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	char* p = NULL;
	char* p1 = NULL;
	char temp[32] = { 0 };
	if ((fp = popen("appm -l", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		result->pid = -1;
		// char *token = strtok(buf, " ");
		// i = 0;
		// while (token != NULL)
		// {
		// 	if (i == 0)
		// 	{
		// 		strcpy(result->name, token);
		// 	}
		// 	else if (i == 1)
		// 	{

		// 		p = strstr(token, "RUNNING");
		// 		if (p)
		// 		{
		// 			strcpy(result->status, "RUNNING");
		// 		}
		// 		p = strstr(token, "STOPPED");
		// 		if (p)
		// 		{
		// 			strcpy(result->status, "STOPPED");
		// 			break;
		// 		}
		// 	}
		// 	else if (i == 2)
		// 	{
		// 		p = strstr(token, "pid:");
		// 		if (p)
		// 		{
		// 			p1 = strstr(token, "\n");
		// 			if (p1)
		// 			{
		// 				memcpy(temp, p + strlen("pid:"), p1 - p - strlen("pid:") + 1);
		// 			}
		// 		}
		// 		p = strstr(temp, "\n");
		// 		if (p)
		// 		{
		// 			*p = '\0';
		// 		}
		// 		result->pid = atoi(temp);
		// 	}
		// 	/* Get next token: */
		// 	token = strtok(NULL, "\t");
		// 	i++;
		// }

		char name[64];
		char status[32];
		int pid;

		// 移除行尾的换行符
		buf[strcspn(buf, "\n")] = 0;

		// 解析每行数据
		if (strstr(buf, "RUNNING") != NULL)
		{
			// 对于运行中的进程，格式为: "Name RUNNING pid:123"
			if (sscanf(buf, "%s RUNNING pid:%d", name, &pid) == 2)
			{
				strncpy(result->name, name, sizeof(result->name) - 1);
				strcpy(result->status, "RUNNING");
				result->pid = pid;
			}
		}
		else if (strstr(buf, "STOPPED") != NULL)
		{
			// 对于停止的进程，格式为: "Name STOPPED"
			if (sscanf(buf, "%s STOPPED", name) == 1)
			{
				strncpy(result->name, name, sizeof(result->name) - 1);
				strcpy(result->status, "STOPPED");
				result->pid = 0;
			}
		}

		//dzlog_info("appname = %s pid = %d", result->name, result->pid);

		count++;
		result++;
	}
	pclose(fp);
	return count;
}

//////////////////////////////////////////
int appInfoReport(PS_DATA_REPORT_CONTAINER_EVENT result)
{
	int ret = appInfoReport0(result); // result->pid result->status result->name
	if (ret > 0)
	{
		ret = appInfoReport2(result, ret); // result->cpuUsed result->memUsed
		if (ret > 0)
		{
			ret = appInfoReport3(result, ret); // result->version result->deployTime
			if (ret > 0)
			{
				ret = appInfoReport4(result, ret); // result->appId
			}
		}
	}
	return ret;
}

int containerInfoReport(PS_DATA_REPORT_CONTAINER_EVENT result)
{
	int ret = containerInfoReport0(result); // name
	if (ret > 0)
	{
		ret = containerInfoReport2(result, ret); // status、deployTime
		if (ret > 0)
		{
			ret = containerInfoReport5(result, ret); // id、containerId、type
			if (ret > 0)
			{
				ret = containerInfoReport4(result, ret); // diskUsed
				if (ret > 0)
				{
					ret = containerInfoReport3(result, ret); // cpuUsed、memUsed
				}
			}
		}
	}

	return ret;
}
//////////////////////////////////////////
/// docker
int serverInfoReport2(PS_DATA_REPORT_SERVER result, int count)
{
	FILE* fp = NULL;
	char cmd[128] = { 0 };
	char buf[128] = { 0 };
	int i = 0;
	for (; i < count; ++i)
	{
		sprintf(cmd, "%s status", result->path);
		if ((fp = popen(cmd, "r")) == NULL)
		{
			return -1;
		}
		while (fgets(buf, 128, fp) != NULL)
		{
			char* p = strstr(buf, "running");
			if (p)
			{
				strcpy(result->status, "running");
			}
			else
			{
				strcpy(result->status, "Inactive");
			}
		}
		result++;
	}
	pclose(fp);
	return count;
}
int serverInfoReport03(PS_DATA_REPORT_SERVER result, int count)
{
	char cmd[128] = { 0 };
	char buf[128] = { 0 };
	int i = 0;
	for (; i < count; ++i)
	{
		char* p3 = strstr(result->name, ".");
		if (p3)
		{
			char name[128] = { 0 };
			memcpy(name, result->name, p3 - result->name);
			sprintf(cmd, "whereis %s", name);
			int ret = popenCmd(cmd, buf);

			(buf[strlen(buf) - 1] == '\n') && (buf[strlen(buf) - 1] = '\0');

			strcpy(result->path, buf);
		}
		result++;
	}
	// dzlog_info("serverInfoReport03 start");
	return count;
}

int toGetServerPid(char* ServerName, char* pid)
{
	int ret = -1;
	FILE* fp = NULL;
	char buf[256] = { 0 };
	char cmd[128] = { 0 };
	sprintf(cmd, "systemctl show %s --property=MainPID", ServerName);
	if ((fp = popen(cmd, "r")) == NULL)
	{
		ret = -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		char* pid_start = strchr(buf, '='); // 定位等号位置
		if (pid_start != NULL)
		{
			pid_start++;						 // 跳过等号
			char* pos = strchr(pid_start, '\n'); // 查找换行符地址
			if (pos != NULL)
			{
				*pos = '\0'; // 直接修改该位置为终止符
			}
			// printf("PID: %s\n", pid_start); // 输出1926
			sprintf(pid, "%s", pid_start);
			ret = 0;
		}
		else
		{
			ret = -1;
		}
	}
	pclose(fp);
	return ret;
}

bool toGetServerPath(const char* name, char* path)
{
	if (!name || !path)
		return false;

	// 构建命令
	char cmd[255];
	sprintf(cmd, "systemctl show %s --property=ExecStart --no-pager", name);

	// 执行命令并读取输出
	FILE* fp = popen(cmd, "r");
	if (!fp)
		return false;

	char line[1024];
	bool found = false;

	while (fgets(line, sizeof(line), fp))
	{
		// 定位 ExecStart 行
		char* exec_start = strstr(line, "ExecStart=");
		if (!exec_start)
			continue;

		// 提取 path= 后的路径
		char* path_start = strstr(exec_start, "path=");
		if (!path_start)
			break;
		path_start += 5; // 跳过 "path="

		// 截断到分号或空格
		char* path_end = strpbrk(path_start, " ;");
		if (!path_end)
			path_end = path_start + strlen(path_start);

		// 计算长度并复制到输出缓冲区
		size_t path_len = path_end - path_start;
		if (path_len == 0)
			break;

		strncpy(path, path_start, path_len);
		path[path_len] = '\0';
		found = true;
		break;
	}

	pclose(fp);
	return found;
}

int check_connection(const char* pid)
{
	char path[256];
	FILE* fp;
	int has_tcp = 0, has_udp = 0;

	// 构建TCP连接文件路径
	snprintf(path, sizeof(path), "/proc/%s/net/tcp", pid);
	if ((fp = fopen(path, "r")) != NULL)
	{
		char line[512];
		fgets(line, sizeof(line), fp); // 跳过表头
		if (fgets(line, sizeof(line), fp) != NULL)
			has_tcp = 1;
		fclose(fp);
	}

	// 构建UDP连接文件路径
	snprintf(path, sizeof(path), "/proc/%s/net/udp", pid);
	if ((fp = fopen(path, "r")) != NULL)
	{
		char line[512];
		fgets(line, sizeof(line), fp); // 跳过表头
		if (fgets(line, sizeof(line), fp) != NULL)
			has_udp = 1;
		fclose(fp);
	}

	// 优先级判断：TCP > UDP > 无连接
	return has_tcp ? 1 : (has_udp ? 2 : -1);
}

int serverInfoReport01(PS_DATA_REPORT_SERVER result)
{
	char buf[256] = { 0 };

	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;
	int flag = 0;
	int end = 0;
	int abandon = 0;
	// 
	if ((fp = popen("systemctl list-units --type=service --no-pager", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	dzlog_debug("serverInfoReport01 1");
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag == 0)
		{
			flag++;
			continue;
		}
		char* p999 = strstr(buf, "LOAD   = Reflects whether the unit definition was properly loaded.");
		if (p999)
		{
			break;
		}
		i = 0;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i > 4)
			{
			}
			char* p = strstr(token, "\n");
			if (p)
			{
				if (i == 0)
				{
					dzlog_debug("serverInfoReport01 3 token[%s]", token);
					end = 1;
					break;
				}
				*p = '\0';
			}

			char cTime[32] = { 0 };
			int ret = systemDate(cTime);
			strcpy(result->installedTime, cTime);
			strcpy(result->updatedTime, cTime);
			if (i == 0)
			{

				if (strlen(token) < 2)
				{
					// 丢弃服务名长度小于2的数据
					abandon = 1;
					break;
				}
				char* p_t = strstr(token, "●");
				if (p_t)
				{
					i--;
				}
				strcpy(result->name, token);
			}
			else if (3 == i)
			{
				char* p2 = strstr(token, "running");
				// char* p3 = strstr(token, "exited");
				if (p2 /* || p3*/)
				{
					strcpy(result->status, "running"); // patch
				}
				else
				{
					strcpy(result->status, "inactive");
				}
			}
			else if (i >= 4)
			{
				strcat(result->description, token);
				strcat(result->description, " ");
			}
			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
		if (abandon == 1)
		{
			continue;
		}
		if (end == 1)
		{
			break;
		}
		strcpy(result->isAutoStarted, "disabled");

		(result->description[strlen(result->description) - 1] == '\n') && (result->description[strlen(result->description) - 1] = '\0');
		result++;
		if (count >= 60)
		{
			break;
		}
		count++;
		// usleep(100000);
	}
	pclose(fp);

	return count;
}

int serverInfoReport02(PS_DATA_REPORT_SERVER result, int count)
{

	char buf[256] = { 0 };

	int i = 0;
	FILE* fp = NULL;
	int count2 = 0;
	char* pStr = NULL;
	int flag = 0;
	int find = 0;
	int end = 0;

	S_DATA_REPORT_SERVER autoBuf[300] = { 0 };
	if ((fp = popen("systemctl list-unit-files --type=service --no-pager", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	// usleep(100000);
	while (fgets(buf, 255, fp) != NULL)
	{
		find = 0;
		if (flag == 0)
		{
			flag++;
			continue;
		}
		char* p999 = strstr(buf, "unit files listed.");
		if (p999)
		{
			break;
		}
		i = 0;
		// PS_DATA_REPORT_SERVER pResult = result;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			/* While there are tokens in "string" */
			// printf( "%s\n", token );

			// //dzlog_info("count2[%d]i[%d]token[%s]",count2,i,token);
			if (i >= 3)
			{
				break;
			}
			char* p = strstr(token, "\n");
			if (p)
			{
				if (i == 0)
				{
					end = 1;
					break;
				}
				*p = '\0';
			}

			if (i == 0)
			{
				/*
					int j = 0;

					for(;j < count;++j)
					{
						if(strcmp(pResult->name,token) == 0)
						{
							find = 1;
							break;
						}
						pResult++;
					}*/
				strcpy(autoBuf[count2].name, token);
			}
			else if (2 == i)
			{

				char* p2 = strstr(token, "enabled");
				if (p2)
				{
					strcpy(autoBuf[count2].isAutoStarted, "enabled");
				}
				else
				{
					strcpy(autoBuf[count2].isAutoStarted, "disabled");
				}
			}
			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
		// result++;
		if (end == 1)
		{
			break;
		}
		count2++;
		// usleep(100000);
	}
	int k, l;
	for (k = 0; k < count; ++k)
	{
		for (l = 0; l < count2; l++)
		{
			// //dzlog_info("k[%d]l[%d]autoBuf[l].name[%s]result->name[%s]",k,l,autoBuf[l].name,result->name);
			if (strcmp(result->name, autoBuf[l].name) == 0)
			{
				strcpy(result->isAutoStarted, autoBuf[l].isAutoStarted);
				// //dzlog_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				break;
			}
		}
		result++;
	}
	// dzlog_info("serverInfoReport02 end count[%d]", count);
	pclose(fp);
	return count;
}

int serverInfoReport02_V1(PS_DATA_REPORT_SERVER result, PS_DATA_REPORT_SERVER pResult, int count) 
{
	char buf[256] = { 0 };

	int i = 0;
	FILE* fp = NULL;
	int count2 = 0;
	char* pStr = NULL;
	int flag = 0;
	int find = 0;
	int end = 0;
	S_DATA_REPORT_SERVER autoBuf[300] = { 0 };
	if ((fp = popen("systemctl list-unit-files --type=service --no-pager", "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	// usleep(100000);
	while (fgets(buf, 255, fp) != NULL)
	{
		find = 0;
		if (flag == 0)
		{
			flag++;
			continue;
		}
		char* p999 = strstr(buf, "unit files listed.");
		if (p999)
		{
			break;
		}
		i = 0;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i >= 3)
			{
				break;
			}
			char* p = strstr(token, "\n");
			if (p)
			{
				if (i == 0)
				{
					end = 1;
					break;
				}
				*p = '\0';
			}

			if (i == 0)
			{
				strcpy(autoBuf[count2].name, token);
			}

			token = strtok(NULL, " ");
			i++;
		}
		if (end == 1)
		{
			break;
		}
		count2++;
		if (count2 >= 200)
		{
			break;
		}
	}

	int k, l;
	int count1 = 0;
	for (l = 0; l < count2; l++)
	{
		for (k = 0; k < count; ++k)
		{

			if (strcmp(result[k].name, autoBuf[l].name) == 0)
			{
				break;
			}
			if (k == count - 1)
			{
				strcpy(result[count1 + count].name, autoBuf[l].name);
				strcpy(result[count1 + count].status, "inactive");
				strcpy(result[count1 + count].description, autoBuf[l].name);
				count1++;
			}
		}
	}

	pclose(fp);
	return count + count1;
}

int ServerInfoPlus(PS_DATA_REPORT_SERVER result, int count)
{
	int k, l;
	for (k = 0; k < count; ++k)
	{
		toGetServerPid(result->name, result->pid);
		toGetServerPath(result->name, result->path);
		if (result->pid != NULL && strlen(result->pid) != 0 && strcmp(result->pid, "0") != 0)
		{
			strcpy(result->status, "running");
			int tet_status = check_connection(result->pid);
			if (tet_status == 1)
			{
				strcpy(result->procotolName, "tcp");
				strcpy(result->protocolType, "tcp");
				strcpy(result->protocolVersion, "1.0");
			}
			else if (tet_status == 2)
			{
				strcpy(result->procotolName, "udp");
				strcpy(result->protocolType, "udp");
				strcpy(result->protocolVersion, "1.0");
			}
			else
			{
				memset(result->procotolName, 0, sizeof(result->procotolName));
				memset(result->protocolType, 0, sizeof(result->protocolType));
				memset(result->protocolVersion, 0, sizeof(result->protocolVersion));
			}
		}
		else
		{
			strcpy(result->status, "inactive");
			memset(result->procotolName, 0, sizeof(result->procotolName));
			memset(result->protocolType, 0, sizeof(result->protocolType));
			memset(result->protocolVersion, 0, sizeof(result->protocolVersion));
		}
		result++;
	}
	// dzlog_info("serverInfoPlus end count[%d]", count);
	return count;
}
int serverInfoReport0(PS_DATA_REPORT_SERVER result)
{
	PS_DATA_REPORT_SERVER pResult = result;
	int ret = serverInfoReport01(result); // isAutoStarted description status name updatedTime installedTime
	dzlog_debug("serverInfoReport0 serverInfoReport01 end ret[%d]", ret);
	if (ret <= 0)
	{
		return ret;
	}
	ret = serverInfoReport02_V1(result, pResult, ret); // isAutoStarted name
	dzlog_debug("serverInfoReport0 serverInfoReport02_V1 end ret[%d]", ret);
	if (ret <= 0)
	{
		return ret;
	}
	pResult = result;
	ret = serverInfoReport02(pResult, ret); // isAutoStarted name
	//dzlog_debug("serverInfoReport0 serverInfoReport02 end ret[%d]", ret);
	pResult = result;
	ret = ServerInfoPlus(pResult, ret); // pid，status，protocolType，path
	//dzlog_debug("serverInfoReport0 ServerInfoPlus end ret[%d]", ret);
	return ret;

}
int portInfoReport0(PS_DATA_REPORT_PORT result)
{
	char buf[256];

	int flag = 0;
	char* p[7] = { 0 };
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char* pStr = NULL;

	if ((fp = popen("netstat -anp", "r")) == NULL)
	{
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag < 2)
		{
			flag++;
			continue;
		}
		char* p9 = strstr(buf, "Active UNIX domain sockets");
		if (p9)
		{
			// //dzlog_info("===p9[%p]",p9);
			// while (fgets(buf, 255, fp) != NULL);
			break;
			// fclose(fp);
			// return count;
		}
		// //dzlog_info("---p9[%p]",p9);
		p[0] = result->protocol;

		p[3] = result->localIp;
		p[4] = result->foreignIp;
		p[5] = result->state;
		p[6] = result->pName;
		///

		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i >= 7)
			{
				break;
			}

			if (i != 1 && i != 2)
			{
				if (i == 6)
				{
					strcpy(p[i], token);
				}
				else
				{
					strcpy(p[i], token);
				}
			}
			// #endif

			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
		if (i < 3)
		{
			i = 0;
			continue;
		}
		i = 0;
		/*
		if(strstr(result->localIp,"::") || strstr(result->foreignIp,"::"))
		{
			//dzlog_info("!!!");
			continue;
		}*/
		// //dzlog_info("111");

		char* p1 = result->localIp + strlen(result->localIp);
		while (*p1 != ':')
		{
			p1--;
		}
		if (p1)
		{
			*p1 = '\0';
			strcpy(result->localPort, p1 + 1);
		}

		// //dzlog_info("p1[%p]",p1);
		char* p2 = result->foreignIp + strlen(result->foreignIp);
		while (*p2 != ':')
		{
			p2--;
		}
		if (p2)
		{
			*p2 = '\0';
			strcpy(result->foreignPort, p2 + 1);
		}
		char* p3 = strstr(result->pName, "/");
		if (p3)
		{
			*p3 = '\0';
			char* p4 = strstr(p3 + 1, "\n");
			// //dzlog_info("p3[%p]",p3);
			if (p4)
			{
				*p4 = '\0';
			}
			result->pid = atoi(result->pName);
			strcpy(result->pName, p3 + 1);
		}
		else
		{
			result->pid = -1;
			strcpy(result->pName, "");
			continue;
		}
		// #endif
		result++;
		count++;
		if (count >= 200)
		{
			break;
		}

		// //dzlog_info("count[%d]",count);
	}
	pclose(fp);
	// dzlog_info("count[%d]", count);
	return count;
}
int propcessInfoReport(PS_DATA_REPORT_PROCESS_EVENT result)
{
	int count = 0;
	int count2 = 0;
	// 全量上报
	g_old_process_count = 0;
	memset(g_old_process, 0, sizeof(S_DATA_REPORT_PROCESS) * 330);
	if (g_old_process_count == 0)
	{
		count = propcessInfoReport0(g_old_process); // pid user state cmd
		if (count > 0)
		{
			// int jj = 0;
			propcessInfoReport2(g_old_process, count);
			propcessInfoReport3(g_old_process, count); //group,gid,user,uid,user
			propcessInfoReport4(g_old_process, count);
			propcessInfoReport6(g_old_process, count);
			int i = 0;
			for (; i < count; ++i)
			{
				strcpy(result->eventType, "newProcess");
				result->isFull = 1;
				memcpy(&result->process, &g_old_process[g_old_process_count], sizeof(S_DATA_REPORT_PROCESS));
				// memcpy(&g_old_process[g_old_process_count],oldResult,sizeof(S_DATA_REPORT_PROCESS));
				result++;
				g_old_process_count++;
			}
			return count;
		}
	}
	else
	{
		PS_DATA_REPORT_PROCESS oldResult = (PS_DATA_REPORT_PROCESS)malloc(sizeof(S_DATA_REPORT_PROCESS) * 200);
		memset(oldResult, 0, sizeof(S_DATA_REPORT_PROCESS) * 200);
		count = propcessInfoReport0(oldResult); // pid user state cmd
		// dzlog_info("propcessInfoReport0 count[%d]", count);
		if (count > 0)
		{
			if (count == g_old_process_count)
			{
				// free(oldResult);
				// return 0;
			}
			propcessInfoReport2(oldResult, count); // cpuUsage memUsage
			// dzlog_info("propcessInfoReport2 count[%d]", count);
			propcessInfoReport3(oldResult, count);
			// dzlog_info("propcessInfoReport3 count[%d]", count);
			propcessInfoReport4(oldResult, count);
			propcessInfoReport6(oldResult, count);
			int i = 0;
			int j = 0;
			int flag = 0;
			// del
			for (i = 0; i < g_old_process_count; ++i)
			{
				flag = 0;
				for (j = 0; j < count; ++j)
				{
					if (strcmp(g_old_process[i].pid, oldResult[j].pid) == 0)
					{
						flag = 1;
						break;
					}
				}
				if (flag == 0)
				{
					strcpy(result->eventType, "delProcess");
					result->isFull = 1;

					memcpy(&result->process, &g_old_process[i], sizeof(S_DATA_REPORT_PROCESS));

					result++;
					count2++;
				}
			}
			// new
			for (i = 0; i < count; ++i)
			{
				flag = 0;
				for (j = 0; j < g_old_process_count; ++j)
				{
					if (strcmp(g_old_process[j].pid, oldResult[i].pid) == 0)
					{

						flag = 1;
						break;
					}
				}
				if (strlen(oldResult[i].pName) == 0 || strcmp(oldResult[i].pName, "") == 0)
				{
					strcpy(result->eventType, "delProcess");
					result->isFull = 1;
					memcpy(&result->process, &oldResult[i], sizeof(S_DATA_REPORT_PROCESS));
					result++;
					count2++;
				}
				else if (flag == 0)
				{
					strcpy(result->eventType, "newProcess");
					result->isFull = 1;
					memcpy(&result->process, &oldResult[i], sizeof(S_DATA_REPORT_PROCESS));
					result++;
					count2++;
				}
			}
			// update
			int count3 = propcessInfoReport5(oldResult, count, result);
			g_old_process_count = count;
			memcpy(g_old_process, oldResult, sizeof(S_DATA_REPORT_PROCESS) * g_old_process_count);
			count = count2 + count3;
			free(oldResult);
		}
		free(oldResult);
	}
	dzlog_info("propcessInfoReport start");
	return count;
}

int serverInfoReport(PS_DATA_REPORT_SERVER_EVENT result)
//int serverInfoReport(void* result_tmp)
{
	int count = 0;
	int count2 = 0;
	int old_server_count = 0;

	PS_DATA_REPORT_SERVER old_server = (PS_DATA_REPORT_SERVER)malloc(sizeof(S_DATA_REPORT_SERVER) * 250);
	if (old_server == NULL)
	{
		return -1;
	}
	memset(old_server, 0, sizeof(S_DATA_REPORT_PROCESS) * 250);

	if (old_server_count == 0)
	{
		count = serverInfoReport0(old_server);
		if (count > 0)
		{
			int i = 0;
			// serverInfoReport2(old_server,count);
			for (; i < count; ++i)
			{
				if (old_server[old_server_count].name == NULL || strlen(old_server[old_server_count].name) == 0)
				{
					old_server_count++;
					continue;
				}
				if (strcmp(old_server[old_server_count].status, "inactive") == 0)
				{
					memset(old_server[old_server_count].pid, 0, 16);
				}
				strcpy(result->eventType, "newService");
				result->isFull = 1;
				memcpy(&result->server, &old_server[old_server_count], sizeof(S_DATA_REPORT_SERVER));
				result++;
				old_server_count++;
			}
			count2 = count;
		}
	}
	else
	{
		S_DATA_REPORT_SERVER oldResult[250] = { 0 };
		count = serverInfoReport0(oldResult);
		dzlog_info("serverInfoReport 11 22 count[%d]", count);
		int i = 0;
		int j = 0;
		int flag = 0;
		// del 
		for (; i < old_server_count; ++i)
		{
			// //dzlog_info("serverInfoReport0 i[%d]",i);
			flag = 0;
			for (j = 0; j < count; ++j)
			{
				if (strcmp(old_server[i].name, oldResult[j].name) == 0)
				{
					flag = 1;
					break;
				}
			}
			if (flag == 0)
			{
				strcpy(result->eventType, "delService");
				strcpy(old_server[i].status, "inactive");
				memset(old_server[i].pid, 0, 16);
				result->isFull = 0;
				memcpy(&result->server, &old_server[i], sizeof(S_DATA_REPORT_SERVER));
				result++;
				count2++;
			}
		}
		// new
		i = 0;

		for (; i < count; ++i)
		{
			flag = 0;
			for (j = 0; j < old_server_count; ++j)
			{
				if (strcmp(old_server[j].name, oldResult[i].name) == 0)
				{
					flag = 1;
					break;
				}
			}
			if (flag == 0)
			{
				strcpy(result->eventType, "newService");
				result->isFull = 0;
				memcpy(&result->server, &old_server[j], sizeof(S_DATA_REPORT_SERVER));
				result++;
				count2++;
			}
		}
		// update
		i = 0;
		for (; i < count; ++i)
		{
			flag = 0;
			for (j = 0; j < old_server_count; ++j)
			{
				if (strcmp(old_server[j].name, oldResult[i].name) == 0)
				{
					if (strcmp(old_server[j].status, oldResult[i].status) != 0)
					{
						flag = 1;
					}
					break;
				}
			}
			if (flag == 1)
			{
				strcpy(result->eventType, "updateService");
				result->isFull = 0;
				if (strcmp(oldResult[i].status, "inactive") == 0)
				{
					memset(old_server[i].pid, 0, 16); // 0807
				}
				memcpy(&result->server, &oldResult[i], sizeof(S_DATA_REPORT_SERVER));
				result++;
				count2++;
			}
		}
		old_server_count = count;
		memcpy(old_server, oldResult, sizeof(S_DATA_REPORT_SERVER) * old_server_count);
	}

	free_s(old_server);
	return count2;
}

int _serverInfoReport(PS_DATA_REPORT_SERVER_EVENT result)
{

	int count = 0;
	int count2 = 0;
	// printf("serverInfoReport 11111111111111111\n");
	S_DATA_REPORT_SERVER oldResult[50] = { 0 };
	// //dzlog_info("serverInfoReport 2222222222222222222222");
	// printf("serverInfoReport 22222222222222222\n");
	// //dzlog_info("serverInfoReport0 g_old_server_count[%d]",g_old_server_count);
	return 0;
}

int portInfoReport(PS_DATA_REPORT_PORT_EVENT result)
{
	int count = 0;
	int count2 = 0;

	S_DATA_REPORT_PORT oldResult[200] = { 0 };
	g_old_port_count = 0;
	memset(g_old_port, 0, sizeof(S_DATA_REPORT_PORT) * 200);
	if (g_old_port_count == 0)
	{
		count = portInfoReport0(g_old_port);
		if (count > 0)
		{
			int i = 0;
			for (; i < count; ++i)
			{
				strcpy(result->eventType, "newLink");
				result->isFull = 1;
				memcpy(&result->port, &g_old_port[g_old_port_count], sizeof(S_DATA_REPORT_PORT));
				result++;
				g_old_port_count++;
			}
		}
		return count;
	}
	else
	{
		// return 0;
		count = portInfoReport0(oldResult);
		// dzlog_info("portInfoReport count[%d]", count);
		if (count == g_old_port_count)
		{
			// return 0;
		}
		int i = 0;
		int j = 0;
		int flag = 0;
		char buf1[255] = { 0 };
		char buf2[255] = { 0 };
		// del
		for (; i < g_old_port_count; ++i)
		{
			sprintf(buf1, "%s%s%s%s%s", g_old_port[i].localIp, g_old_port[i].localPort, g_old_port[i].foreignIp, g_old_port[i].foreignPort, g_old_port[i].protocol);
			// //dzlog_info("buf1[%s] i[%d]",buf1,i);
			flag = 0;
			for (j = 0; j < count; ++j)
			{

				sprintf(buf2, "%s%s%s%s%s", oldResult[j].localIp, oldResult[j].localPort, oldResult[j].foreignIp, oldResult[j].foreignPort, oldResult[j].protocol);

				// //dzlog_info("buf2[%s] j[%d]",buf2,j);
				if (strcmp(buf1, buf2) == 0)
				{
					flag = 1;
					break;
				}
			}
			if (flag == 0)
			{
				strcpy(result->eventType, "delLink");
				result->isFull = 1;
				memcpy(&result->port, &g_old_port[i], sizeof(S_DATA_REPORT_PORT));
				// sprintf(buf1,"%s%s%s%s%s",g_old_port[i].localIp,g_old_port[i].localPort,g_old_port[i].foreignIp,g_old_port[i].foreignPort,g_old_port[i].protocol);
				// //dzlog_info("buf1[%s] i[%d]",buf1,i);
				result++;
				count2++;
			}
		}
		// new
		i = 0;

		for (; i < count; ++i)
		{
			sprintf(buf2, "%s%s%s%s%s", oldResult[i].localIp, oldResult[i].localPort, oldResult[i].foreignIp, oldResult[i].foreignPort, oldResult[i].protocol);
			// //dzlog_info("buf2[%s] i[%d]",buf2,i);
			flag = 0;
			for (j = 0; j < g_old_port_count; ++j)
			{

				sprintf(buf1, "%s%s%s%s%s", g_old_port[j].localIp, g_old_port[j].localPort, g_old_port[j].foreignIp, g_old_port[j].foreignPort, g_old_port[j].protocol);
				// //dzlog_info("buf1[%s] j[%d]",buf1,j);
				if (strcmp(buf1, buf2) == 0)
				{
					flag = 1;
					break;
				}
			}
			if (flag == 0)
			{
				strcpy(result->eventType, "newLink");
				result->isFull = 1;
				memcpy(&result->port, &oldResult[i], sizeof(S_DATA_REPORT_PORT));
				// sprintf(buf1,"%s%s%s%s%s",g_old_port[j].localIp,g_old_port[j].localPort,g_old_port[j].foreignIp,g_old_port[j].foreignPort,g_old_port[j].protocol);
				// //dzlog_info("buf1[%s] j[%d]",buf1,j);
				result++;
				count2++;
			}
		}
		// update
		// update
		i = 0;

		for (; i < count; ++i)
		{
			sprintf(buf2, "%s%s%s%s%s", oldResult[i].localIp, oldResult[i].localPort, oldResult[i].foreignIp, oldResult[i].foreignPort, oldResult[i].protocol);
			flag = 0;
			for (j = 0; j < g_old_port_count; ++j)
			{
				sprintf(buf1, "%s%s%s%s%s", g_old_port[j].localIp, g_old_port[j].localPort, g_old_port[j].foreignIp, g_old_port[j].foreignPort, g_old_port[j].protocol);
				if (strcmp(buf2, buf1) == 0)
				{
					if (strcmp(g_old_port[j].state, oldResult[i].state) != 0)
					{
						flag = 1;
					}
					break;
				}
			}
			if (flag == 1)
			{
				strcpy(result->eventType, "updateLink");
				result->isFull = 1;
				memcpy(&result->port, &oldResult[i], sizeof(S_DATA_REPORT_PORT));
				result++;
				count2++;
			}
		}
		g_old_port_count = count;
		memcpy(g_old_port, oldResult, sizeof(S_DATA_REPORT_PORT) * g_old_port_count);
	}
	return count2;
}

int _fullInfoReport(char* cmd, void* result)
{
	// dzlog_info("fullInfoReport !!!!!!   cmd[%s]", cmd);
	int count = 0;

	if (strcmp("process", cmd) == 0)
	{
		PS_DATA_REPORT_PROCESS_EVENT p = (PS_DATA_REPORT_PROCESS_EVENT)result;
		PS_DATA_REPORT_PROCESS fullResult = (PS_DATA_REPORT_PROCESS)malloc(sizeof(S_DATA_REPORT_PROCESS) * 330);
		count = propcessInfoReport0(fullResult);
		// dzlog_info("fullInfoReport propcessInfoReport0 count[%d]", count);
		if (count > 0)
		{
			propcessInfoReport2(fullResult, count);
			propcessInfoReport3(fullResult, count);
			propcessInfoReport4(fullResult, count);
			propcessInfoReport6(fullResult, count);
			// dzlog_info("fullInfoReport propcessInfoReport4 count[%d]", count);
			int i = 0;
			for (; i < count; i++)
			{
				//	//dzlog_info("fullInfoReport propcessInfoReport4 fullResult[i].pid[%s],fullResult[i].pName[%s]", fullResult[i].pid, fullResult[i].pName);
				strcpy(p->eventType, "newProcess");
				p->isFull = 1;
				memcpy(&p->process, &fullResult[i], sizeof(S_DATA_REPORT_PROCESS));
				//	//dzlog_info("fullInfoReport propcessInfoReport4 p->process.pid[%s], p->process.pName[%s]", p->process.pid, p->process.pName);
				//	//dzlog_info("fullInfoReport propcessInfoReport4 1p->isFull [%d]", p->isFull);
				p++;
				//	//dzlog_info("fullInfoReport propcessInfoReport4 2p->isFull [%d]", p->isFull);
			}
			free(fullResult);
			return count;
		}
		free(fullResult);
	}
	return 0;
}
int fullInfoReport(char* cmd, void* result)
{
	// dzlog_info("fullInfoReport !!!!!!   cmd[%s]", cmd);
	int count = 0;

	if (strcmp("process", cmd) == 0)
	{
		PS_DATA_REPORT_PROCESS_EVENT p = (PS_DATA_REPORT_PROCESS_EVENT)result;
		PS_DATA_REPORT_PROCESS fullResult = (PS_DATA_REPORT_PROCESS)malloc(sizeof(S_DATA_REPORT_PROCESS) * 330);
		count = propcessInfoReport0(fullResult);
		// dzlog_info("fullInfoReport propcessInfoReport0 count[%d]", count);
		if (count > 0)
		{

			propcessInfoReport2(fullResult, count); //top
			propcessInfoReport3(fullResult, count);
			propcessInfoReport4(fullResult, count);
			propcessInfoReport6(fullResult, count);
			// dzlog_info("fullInfoReport propcessInfoReport4 count[%d]", count);
			int i = 0;
			for (; i < count; i++)
			{
				//	//dzlog_info("fullInfoReport propcessInfoReport4 fullResult[i].pid[%s],fullResult[i].pName[%s]", fullResult[i].pid, fullResult[i].pName);
				strcpy(p->eventType, "newProcess");
				p->isFull = 1;
				memcpy(&p->process, &fullResult[i], sizeof(S_DATA_REPORT_PROCESS));
				//	//dzlog_info("fullInfoReport propcessInfoReport4 p->process.pid[%s], p->process.pName[%s]", p->process.pid, p->process.pName);
				//	//dzlog_info("fullInfoReport propcessInfoReport4 1p->isFull [%d]", p->isFull);
				p++;
				//	//dzlog_info("fullInfoReport propcessInfoReport4 2p->isFull [%d]", p->isFull);
			}
			free(fullResult);
			return count;
		}
		free(fullResult);
	}
	else if (strcmp("service", cmd) == 0)
	{
		PS_DATA_REPORT_SERVER_EVENT p = (PS_DATA_REPORT_SERVER_EVENT)result;
		PS_DATA_REPORT_SERVER fullResult = (PS_DATA_REPORT_SERVER)malloc(sizeof(S_DATA_REPORT_SERVER) * 250);
		count = serverInfoReport0(fullResult);
		// dzlog_info("fullInfoReport serverInfoReport0 count[%d]", count);
		if (count > 0)
		{
			int i = 0;
			// serverInfoReport2(g_old_server,count);
			for (; i < count; ++i)
			{
				strcpy(p->eventType, "newService");
				p->isFull = 1;
				memcpy(&p->server, &fullResult[i], sizeof(S_DATA_REPORT_SERVER));
				p++;
			}
			free(fullResult);
			return count;
		}
		free(fullResult);
	}
	else if (strcmp("netstat", cmd) == 0)
	{
		PS_DATA_REPORT_PORT_EVENT p = (PS_DATA_REPORT_PORT_EVENT)result;
		PS_DATA_REPORT_PORT fullResult = (PS_DATA_REPORT_PORT)malloc(sizeof(S_DATA_REPORT_PORT) * 200);

		count = portInfoReport0(fullResult);
		// dzlog_info("fullInfoReport portInfoReport count[%d]", count);

		if (count > 0)
		{
			int i = 0;
			for (; i < count; ++i)
			{

				strcpy(p->eventType, "newLink");
				p->isFull = 1;
				memcpy(&p->port, &fullResult[i], sizeof(S_DATA_REPORT_PORT));
				p++;
				// //dzlog_info("portInfoReport i[%d]",i);
			}
			free(fullResult);
			return count;
		}
		free(fullResult);
	}
	return count;
}
static void proCommen(double value, PS_DATA_REPORT_PARAM pDataParam)
{
	if (pDataParam->min == 0)
	{
		pDataParam->min = value;
	}
	pDataParam->min > value && (pDataParam->min = value);
	if (pDataParam->max == 0)
	{
		pDataParam->max = value;
	}
	pDataParam->max < value && (pDataParam->max = value);
	if (pDataParam->current == 0)
	{
		pDataParam->current = value;
	}
	pDataParam->current = value;

	pDataParam->sum += value;

	pDataParam->count++;
}
static void cpuTemp2(PS_DATA_REPORT_PARAM pDataParam)
{
	char result[255] = { 0 };
	int ret = cpuTemp(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "°C");
	if (p)
	{
		*p = '\0';
	}
	proCommen(atof(result), pDataParam);
}

static void cpuUsage2(PS_DATA_REPORT_PARAM pDataParam)
{
	char result[255] = { 0 };
	int ret = cpuUsed(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "%");
	if (p)
	{
		*p = '\0';
	}
	double value = atof(result);
	if (value == 0)
	{ // 此方法计算cpu使用率时，当使用率较低时，可能算出0值。所以临时方案当为0时，赋一个零点几的值
		srand(time(NULL));
		int randomInt = rand();
		value = (float)randomInt / RAND_MAX;
	}

	proCommen(value, pDataParam);
}

static void cpuUsage2_b(PS_DATA_REPORT_PARAM pDataParam)
{
	char result[255] = { 0 };
	int ret = cpuUsed_b(result);
	if (ret < 0)
	{
		return;
	}

	double value = atof(result);
	value = round(value * 100) / 100;

	proCommen(value, pDataParam);
}

static void memUsage2(PS_DATA_REPORT_PARAM pDataParam)
{
	char result[255] = { 0 };
	int ret = memUsed(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "%");
	if (p)
	{
		*p = '\0';
	}

	proCommen(atof(result), pDataParam);
}
static void cpuUsage3(PS_DATA_REPORT_PARAM pDataParam)
{

	char result[255] = { 0 };
	int ret = cpuUsed(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "%");
	if (p)
	{
		*p = '\0';
	}
	proCommen(atof(result), pDataParam);
}

static void memUsage3(PS_DATA_REPORT_PARAM pDataParam)
{
	char result[255] = { 0 };
	int ret = memUsed(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "%");
	if (p)
	{
		*p = '\0';
	}
	proCommen(atof(result), pDataParam);
}
static void diskUsage2(PS_DATA_REPORT_PARAM pDataParam)
{

	char result[255] = { 0 };
	int ret = diskUsed(result);
	if (ret < 0)
	{
		return;
	}
	char* p = strstr(result, "%");
	if (p)
	{
		*p = '\0';
	}
	proCommen(atof(result), pDataParam);
}

static void netLink2(PS_DATA_REPORT_PARAM pDataParam)
{

	char result[255] = { 0 };
	int ret = 0;
	ret = netLink(result); // test
	// dzlog_info("result[%s]", result);
	if (ret < 0)
	{
		return;
	}
	float fvalue = atof(result);
	g_dataNetwork[g_dataNetworkCount++] = fvalue;
	int ivalue = 1000 * fvalue;
	proCommen(ivalue, pDataParam);
}

static int dataCommen(pFunCommen pFun, PS_DATA_REPORT_PARAM pDataParam)
{
	pFun(pDataParam);
	return 0;
}

static void sumNetwork(double pParam[], int len, PS_DATA_REPORT_PARAM pDataParam, PS_DATA_REPORT_NETWORK pNet)
{
	int lossPct = 0;
	double stddev = 0;
	memset(pNet, 0, sizeof(S_DATA_REPORT_NETWORK));
	pNet->avg = (double)pDataParam->sum / (double)pDataParam->count;
	pNet->avg /= 1000;
	pNet->best = (double)pDataParam->min / 1000;
	pNet->worst = (double)pDataParam->max / 1000;

	int i = 0;
	for (; i < len; ++i)
	{
		pNet->sent += 10;
		if (pParam[i] == 0.0)
		{
			lossPct++;
		}
		else
		{
			pNet->recv += 18;
			stddev += pow((pParam[i] - pNet->avg), 2);
		}
	}
	pNet->lossPct = (double)lossPct / len;
	if (len > 1)
	{
		stddev /= len - 1;
	}
	pNet->stddev = sqrt(stddev);
	pNet->ttl = g_dataNetTtl;
	strcpy(pNet->target, g_dataNetIp);
	S_NETCARD sNetCard[100];
	int ret = wiredModules(sNetCard);
	if (ret > 0)
	{
		strcpy(pNet->host, sNetCard[0].ip);
	}
}

/*
static PS_DATA_REPORT_PROCESS top5Sort(PS_DATA_REPORT_PROCESS *result)
{
	if(*result == NULL)
	{

	}

	int i = 0;
	for(i = 0; i < 5;++i)
	{

	}
	return 5;
}
static int top5Sort(int flag,int index,PS_DATA_REPORT_PROCESS result,PS_DATA_REPORT_PROCESS *result2)
{
	PS_DATA_REPORT_PROCESS pre = *result2;
	PS_DATA_REPORT_PROCESS tmp = NULL;
	if(index < 5)
	{
		if(index == 0)
		{
			*result2 = result;
			return 1;
		}
		int i = 0;
		for(i = 0; i < index;++i)
		{
			if(flag == 0)
			{
				if(atoi(result->cpuUsage) >= atoi(*result->cpuUsage))
				{
					pre = *result2;
					(*result2)++;
					continue;
				}

				tmp = *result2;
				*result2 = pre;

				pre = *result2;
				(*result2)++;
			}
		}
	}
	else
	{

	}
	return index;
}
*/
/*
static void bubble(int arr[], int sz)
{
	for (int j = 0; j < sz - 1; j++)
	{
		int flag = 0;
		for (int i = 0; i < sz-1-j; i++)
		{
			if (arr[i] <arr[i + 1])
			{
				int temp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = temp;
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
	}
}
*/
static void bubble(S_DATA_REPORT_PROCESS2 arr[], int sz)
{
	for (int j = 0; j < sz - 1; j++)
	{
		int flag = 0;
		int value = 0;
		int value2 = 0;
		for (int i = 0; i < sz - 1 - j; i++)
		{

			// printf("arr[i]->memUsage  ,%s\n",arr[i].memUsage);
			// printf("arr[i + 1]->memUsage  ,%s\n",arr[i + 1].memUsage);

			value = atoi(arr[i].memUsage);
			value2 = atoi(arr[i + 1].memUsage);

			if (value < value2)
			{
				S_DATA_REPORT_PROCESS2 temp = { 0 };
				memcpy(&temp, &arr[i], sizeof(S_DATA_REPORT_PROCESS2));
				memcpy(&arr[i], &arr[i + 1], sizeof(S_DATA_REPORT_PROCESS2));
				memcpy(&arr[i + 1], &temp, sizeof(S_DATA_REPORT_PROCESS2));
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
	}
}
static int getMem(char* proId, char* result)
{
	FILE* fp = NULL;

	char buf[255] = { 0 };
	char dir[64] = { 0 };
	sprintf(dir, "/proc/%s/status", proId);
	struct stat st = { 0 };
	if (stat(dir, &st) == -1)
	{
		strcpy(result, "0");
		return -1;
	}

	char cmd[128] = { 0 };
	sprintf(cmd, "cat /proc/%s/status", proId);

	if ((fp = popen(cmd, "r")) == NULL)
	{
		pclose(fp);
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (!strstr(buf, "VmRSS:"))
			continue;
		int i = 0;
		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i == 1)
			{
				char* p = strstr(token, " kB");
				*p = '\0';
				strcpy(result, token);
				pclose(fp);
				return 0;
			}

			/* Get next token: */
			token = strtok(NULL, " ");
		}
	}
	pclose(fp);
	return -1;
}

static int propcessInfoReport52(PS_DATA_REPORT_PROCESS result, int countR, int flagCm)
{
	dzlog_debug("propcessInfoReport52 start countR[%d],flagCm[%d]", countR, flagCm);
	PS_DATA_REPORT_PROCESS presult = result;
	S_DATA_REPORT_PROCESS2 top[50] = { 0 };
	int flag2 = 0;
	int i = 0;
	FILE* fp = NULL;
	int count = 0;
	char buf[255] = { 0 };
	int flag = 0;
	char cmd[32] = { 0 };
	sprintf(cmd, "top -n 1 -b");
	if ((fp = popen(cmd, "r")) == NULL)
	{
		pclose(fp);
		dzlog_error("propcessInfoReport52 top error");
		return -1;
	}
	while (fgets(buf, 255, fp) != NULL)
	{
		if (flag2 < 4)
		{
			flag2++;
			continue;
		}
		if (flag == 0)
		{
			char* p = strstr(buf, "PID USER");
			if (!p)
			{
				continue;
			}
			else
			{
				flag = 1;
				continue;
			}
		}

		char* token = strtok(buf, " ");
		while (token != NULL)
		{
			if (i >= 10)
			{
				break;
			}
			if (i == 0)
			{
				strcpy(top[count].pid, token);
			}
			if (i == 0)
				strcpy(top[count].pid, token);
			if (i == 1)
				strcpy(top[count].user, token);

			if (i == 8)
			{
				strcpy(top[count].cpuUsage, token);
			}

			if (i == 9)
				strcpy(top[count].memUsage, token);

			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
		i = 0;
		count++;
		if (count > countR)
			break;
		// usleep(100);
	}
	pclose(fp);
	int j = 0;
	int k = 0;

	if (flagCm == 1)
	{
		bubble(top, count);
	}

	for (j = 0; j < countR; ++j)
	{
		strcpy(result->pid, top[j].pid);
		strcpy(result->cpuUsage, top[j].cpuUsage);
		strcpy(result->memUsage, top[j].memUsage);
		strcpy(result->user, top[j].user);
		result++;
	}
	propcessInfoReport4(presult, countR);
	return countR;

}

static int top5Cpu(PS_DATA_REPORT_PROCESS result)
{
	//多采五个 防止同步先后采集数据引发的name丢失问题
	return propcessInfoReport52(result, 10, 0);
}

static int top5Mem(PS_DATA_REPORT_PROCESS result)
{
	//多采五个 防止同步先后采集数据引发的name丢失问题
	return propcessInfoReport52(result, 10, 1);
}

static int top5CpuResult(PS_DATA_REPORT_PROCESS result, float* value)
{
	int ret = top5Cpu(result);
	int i = 0;
	*value = 0;
	for (i = 0; i < ret; ++i)
	{

		char* p = NULL;
		p = strstr(result->cpuUsage, "%");
		if (p)
		{
			*p = '\0';
		}
		*value += atof(result->cpuUsage);
		result++;
	}
	return ret;
}

static int top5MemResult(PS_DATA_REPORT_PROCESS result, float* value)
{
	int ret = top5Mem(result);
	int i = 0;
	*value = 0;
	char* p = NULL;
	for (i = 0; i < ret; ++i)
	{
		p = strstr(result->memUsage, "%");
		if (p)
		{
			*p = '\0';
		}
		*value += atof(result->memUsage);
		result++;
	}
	// bubble(result2, ret,1);
	return ret;
}
static void putWireCard(PS_DATA_REPORT_WIRE pcard)
{
	int i = 0;
	int flag = 0;
	// time_t now;
	// time(&now);
	for (; i < g_old_wire_count; ++i)
	{
		if (strcmp(g_old_wire[i].iface, pcard->iface) == 0)
		{
			memcpy(&g_old_wire[i], pcard, sizeof(S_DATA_REPORT_WIRE));
			flag = 1;
			// time(&(g_old_wire[i].second));
		}
	}
	if (flag == 0)
	{
		time(&(g_old_wire[g_old_wire_count].second));
		memcpy(&g_old_wire[g_old_wire_count++], pcard, sizeof(S_DATA_REPORT_WIRE));
	}
}

static PS_DATA_REPORT_WIRE getWireCard(PS_DATA_REPORT_WIRE pcard)
{
	int i = 0;
	for (; i < g_old_wire_count; ++i)
	{
		if (strcmp(g_old_wire[i].iface, pcard->iface) == 0)
		{
			return &g_old_wire[i];
		}
	}
	return NULL;
}

static PS_DATA_REPORT_MEM_SUM getMemSum(PS_DATA_REPORT_MEM_SUM mem)
{

	// S_DATA_REPORT_MEM_SUM memBuf = {0};
	const char* cmd = "free";
	int i = 0;
	FILE* fp = NULL;
	if ((fp = popen(cmd, "r")) == NULL)
	{
		pclose(fp);
		return NULL;
	}
	char buf[255] = { 0 };

	while (fgets(buf, 255, fp) != NULL)
	{
		char* p = strstr(buf, "Mem:");
		if (!p)
		{
			continue;
		}
		char* token = strtok(p + strlen("Mem:"), " ");
		while (token != NULL)
		{
			if (i == 0)
			{
				mem->total = atoi(token);
			}
			else if (1 == i)
			{
				mem->used = atoi(token);
			}
			else if (2 == i)
			{
				mem->free = atoi(token);
			}
			else if (3 == i)
			{
				mem->shared = atoi(token);
			}
			else if (4 == i)
			{
				mem->buff_cache = atoi(token);
			}
			else if (5 == i)
			{
				mem->available = atoi(token);
			}

			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
	}

	pclose(fp);
	return mem;
}

static int memSize2Usage(char* mem, int memTotal, char* result)
{

	float fmem = 0.0;
	fmem = 100 * atof(mem) / memTotal;
	sprintf(result, "%.2f", fmem);
	return 0;
}

// 比较两个设备对象是否相同
int compare_device_object(cJSON* device1, cJSON* device2) {
	// 检查设备类型
	cJSON* device_type1 = cJSON_GetObjectItemCaseSensitive(device1, "deviceType");
	cJSON* device_type2 = cJSON_GetObjectItemCaseSensitive(device2, "deviceType");

	if (!cJSON_IsString(device_type1) || !cJSON_IsString(device_type2) ||
		strcmp(device_type1->valuestring, device_type2->valuestring) != 0) {
		dzlog_info("hasSipInfoChanged device_type diff device_type1[%s],device_type2[%s]", device_type1->valuestring, device_type2->valuestring);
		return 0;
	}
	// 检查 subId
	cJSON* sub_id1 = cJSON_GetObjectItemCaseSensitive(device1, "subId");
	cJSON* sub_id2 = cJSON_GetObjectItemCaseSensitive(device2, "subId");

	if (!cJSON_IsString(sub_id1) || !cJSON_IsString(sub_id2) ||
		strcmp(sub_id1->valuestring, sub_id2->valuestring) != 0) {
		dzlog_info("hasSipInfoChanged sub_id diff sub_id1[%s],sub_id2[%s]", sub_id1->valuestring, sub_id2->valuestring);
		return 0;
	}
	//// 检查 isUse
	//cJSON* is_use1 = cJSON_GetObjectItemCaseSensitive(device1, "isUse");
	//cJSON* is_use2 = cJSON_GetObjectItemCaseSensitive(device2, "isUse");

	//if (!cJSON_IsBool(is_use1) || !cJSON_IsBool(is_use2) ||
	//	cJSON_IsTrue(is_use1) != cJSON_IsTrue(is_use2)) {
	//	return 0;
	//}

	//// 检查 isMultiChannel
	//cJSON* is_multi1 = cJSON_GetObjectItemCaseSensitive(device1, "isMultiChannel");
	//cJSON* is_multi2 = cJSON_GetObjectItemCaseSensitive(device2, "isMultiChannel");

	//if (!cJSON_IsBool(is_multi1) || !cJSON_IsBool(is_multi2) ||
	//	cJSON_IsTrue(is_multi1) != cJSON_IsTrue(is_multi2)) {
	//	return 0;
	//}

	//// 检查 mainId（如果存在）
	//cJSON* main_id1 = cJSON_GetObjectItemCaseSensitive(device1, "mainId");
	//cJSON* main_id2 = cJSON_GetObjectItemCaseSensitive(device2, "mainId");
	//if ((main_id1 != NULL) != (main_id2 != NULL)) {
	//	return 0;
	//}
	//if (main_id1 && main_id2 &&
	//	(!cJSON_IsString(main_id1) || !cJSON_IsString(main_id2) ||
	//		strcmp(main_id1->valuestring, main_id2->valuestring) != 0)) {
	//	return 0;
	//}

	// 检查 deviceName
	cJSON* device_name1 = cJSON_GetObjectItemCaseSensitive(device1, "deviceName");
	cJSON* device_name2 = cJSON_GetObjectItemCaseSensitive(device2, "deviceName");

	if (!cJSON_IsString(device_name1) || !cJSON_IsString(device_name2) ||
		strcmp(device_name1->valuestring, device_name2->valuestring) != 0) {
		dzlog_info("hasSipInfoChanged device_name diff device_name1[%s],device_name2[%s]", device_name1->valuestring, device_name2->valuestring);
		return 0;
	}
	//// 检查 deviceSn
	//cJSON* device_sn1 = cJSON_GetObjectItemCaseSensitive(device1, "deviceSn");
	//cJSON* device_sn2 = cJSON_GetObjectItemCaseSensitive(device2, "deviceSn");

	//if (!cJSON_IsString(device_sn1) || !cJSON_IsString(device_sn2) ||
	//	strcmp(device_sn1->valuestring, device_sn2->valuestring) != 0) {
	//	return 0;
	//}

	return 1;
}

bool hasSipInfoChanged(cJSON* json, cJSON* json1) {

	dzlog_info("hasSipInfoChanged start");
	bool res = false;
	cJSON* sipServer = NULL;
	cJSON* sipServer1 = NULL;
	if (cJSON_HasObjectItem(json, "sipServer") && cJSON_HasObjectItem(json1, "sipServer"))
	{
		sipServer = cJSON_GetObjectItem(json, "sipServer");
		sipServer1 = cJSON_GetObjectItem(json1, "sipServer");
		char sipId[64] = { 0 };
		char sipPort[16] = { 0 };
		char sipProtocol[8] = { 0 };
		char sipIp[64] = { 0 };
		char sipPassword[64] = { 0 };
		char sipId1[64] = { 0 };
		char sipPort1[16] = { 0 };
		char sipProtocol1[8] = { 0 };
		char sipIp1[64] = { 0 };
		char sipPassword1[64] = { 0 };
		if (cJSON_HasObjectItem(sipServer, "sipId")) { strncpy(sipId, cJSON_GetObjectItem(sipServer, "sipId")->valuestring, sizeof(sipId) - 1); }
		if (cJSON_HasObjectItem(sipServer1, "sipId")) { strncpy(sipId1, cJSON_GetObjectItem(sipServer1, "sipId")->valuestring, sizeof(sipId1) - 1); }
		if (strcmp(sipId, sipId1) != 0)
		{
			dzlog_info("hasSipInfoChanged sipId diff sipId[%s],sipId1[%s]", sipId, sipId1);
			res = true;
			goto exit;
		}
		if (cJSON_HasObjectItem(sipServer, "sipPort")) { strncpy(sipPort, cJSON_GetObjectItem(sipServer, "sipPort")->valuestring, sizeof(sipPort) - 1); }
		if (cJSON_HasObjectItem(sipServer1, "sipPort")) { strncpy(sipPort1, cJSON_GetObjectItem(sipServer1, "sipPort")->valuestring, sizeof(sipPort1) - 1); }
		if (strcmp(sipPort, sipPort1) != 0)
		{
			dzlog_info("hasSipInfoChanged sipPort diff sipPort[%s],sipPort1[%s]", sipPort, sipPort1);
			res = true;
			goto exit;
		}
		if (cJSON_HasObjectItem(sipServer, "sipProtocol")) { strncpy(sipProtocol, cJSON_GetObjectItem(sipServer, "sipProtocol")->valuestring, sizeof(sipProtocol) - 1); }
		if (cJSON_HasObjectItem(sipServer1, "sipProtocol")) { strncpy(sipProtocol1, cJSON_GetObjectItem(sipServer1, "sipProtocol")->valuestring, sizeof(sipProtocol1) - 1); }
		if (strcmp(sipProtocol, sipProtocol1) != 0)
		{
			dzlog_info("hasSipInfoChanged sipProtocol diff sipProtocol[%s],sipProtocol1[%s]", sipProtocol, sipProtocol1);
			res = true;
			goto exit;
		}
		if (cJSON_HasObjectItem(sipServer, "sipIp")) { strncpy(sipIp, cJSON_GetObjectItem(sipServer, "sipIp")->valuestring, sizeof(sipIp) - 1); }
		if (cJSON_HasObjectItem(sipServer1, "sipIp")) { strncpy(sipIp1, cJSON_GetObjectItem(sipServer1, "sipIp")->valuestring, sizeof(sipIp1) - 1); }
		if (strcmp(sipIp, sipIp1) != 0)
		{
			dzlog_info("hasSipInfoChanged sipIp diff sipIp[%s],sipIp1[%s]", sipIp, sipIp1);
			res = true;
			goto exit;
		}
		if (cJSON_HasObjectItem(sipServer, "sipPassword")) { strncpy(sipPassword, cJSON_GetObjectItem(sipServer, "sipPassword")->valuestring, sizeof(sipPassword) - 1); }
		if (cJSON_HasObjectItem(sipServer1, "sipPassword")) { strncpy(sipPassword1, cJSON_GetObjectItem(sipServer1, "sipPassword")->valuestring, sizeof(sipPassword1) - 1); }
		if (strcmp(sipPassword, sipPassword1) != 0)
		{
			dzlog_info("hasSipInfoChanged sipPassword diff sipPassword[%s],sipPassword1[%s]", sipPassword, sipPassword1);
			res = true;
			goto exit;
		}
		cJSON* deviceList = NULL;
		cJSON* deviceList1 = NULL;
		if (cJSON_HasObjectItem(json, "deviceList") && cJSON_HasObjectItem(json1, "deviceList"))
		{

			deviceList = cJSON_GetObjectItem(json, "deviceList");
			deviceList1 = cJSON_GetObjectItem(json1, "deviceList");
			cJSON* device = NULL;
			cJSON* device1 = NULL;
			device = cJSON_GetArrayItem(deviceList, 0);
			device1 = cJSON_GetArrayItem(deviceList1, 0);

			char mainId[64] = { 0 };
			char mainId1[64] = { 0 };
			if (cJSON_HasObjectItem(device, "mainId")) { strncpy(mainId, cJSON_GetObjectItem(device, "mainId")->valuestring, sizeof(mainId) - 1); }
			if (cJSON_HasObjectItem(device1, "mainId")) { strncpy(mainId1, cJSON_GetObjectItem(device1, "mainId")->valuestring, sizeof(mainId1) - 1); }
			if (strcmp(mainId, mainId1) != 0)
			{
				dzlog_info("hasSipInfoChanged mainId diff mainId[%s],mainId1[%s]", mainId, mainId1);
				res = true;
				goto exit;
			}
			if (cJSON_HasObjectItem(device, "children") && cJSON_HasObjectItem(device1, "children"))
			{
				cJSON* children = NULL;
				cJSON* children1 = NULL;
				children = cJSON_GetObjectItem(device, "children");
				children1 = cJSON_GetObjectItem(device1, "children");
				if (cJSON_IsArray(children) && cJSON_IsArray(children1))
				{
					if (cJSON_GetArraySize(children) != cJSON_GetArraySize(children1))
					{
						dzlog_info("hasSipInfoChanged children Size diff");
						res = true;
						goto exit;
					}
					else
					{
						//比子设备名称和编码
						// 比较每个子设备
						for (int i = 0; i < cJSON_GetArraySize(children); i++) {
							cJSON* child1 = cJSON_GetArrayItem(children, i);
							cJSON* child2 = cJSON_GetArrayItem(children1, i);
							if (!compare_device_object(child1, child2)) {
								res = true;
								goto exit;
							}
						}
					}
				}
				else
				{
					dzlog_info("hasSipInfoChanged children diff");
					res = true;
					goto exit;
				}
			}
		}
		else
		{
			res = true;
			goto exit;
		}
	}
	else
	{
		res = true;
	}
exit:
	return res;
}

int toSetnvrConfig(char* body, char* path, char* resMsg)
{
	dzlog_info("toSetnvrConfig %s ", path);
	FILE* file = fopen(path, "w");
	if (!file)
	{
		perror("Error opening file for writing");
		return -1;
	}
	fprintf(file, "%s", body);
	fclose(file);

	char trinity[256] = { 0 };
	sprintf(trinity, "chown -R tmp:tmp %s", path);
	system(trinity);
	memset(trinity, 0, 256);
	sprintf(trinity, "chmod 755 %s", path);
	system(trinity);

	return 1;
}

bool hasDataChanged_v1(PCURRENT_ROMACONF current_romaconf, char* mqttIp, int mqttPort, int mqttsPort, char* deviceAuthUser, char* deviceAuthSecret, char* deviceId, int TLS)
{
	bool res = false;

	if (TLS == 1)
	{
		if (strcmp(current_romaconf->current_ServiceIp, mqttIp) != 0)
		{
			dzlog_info("current_ServiceIp[%s] mqttIp[%s]", current_romaconf->current_ServiceIp, mqttIp);
			res = true;
		}
		if (0 == mqttsPort)
		{
			// 说明没获取到mqttsport
			if (1883 == mqttPort)
			{
				if (8443 != mqttsPort)
				{
					res = true;
				}
			}
			else if (11883 == mqttPort)
			{
				if (18443 != mqttsPort)
				{
					res = true;
				}
			}
		}
		else
		{
			if (current_romaconf->current_ServicePort != mqttsPort)
			{
				dzlog_info("ActivationMain current_romaconf->current_ServicePort[%d] != romaconf->mqttsPort[%d]", current_romaconf->current_ServicePort, mqttsPort);
				res = true;
			}
		}
	}
	else
	{
		if (strcmp(current_romaconf->current_ServiceIp, mqttIp) != 0)
		{
			dzlog_info("ActivationMain current_romaconf->current_ServiceIp[%s] romaconf->mqttIp[%s]", current_romaconf->current_ServiceIp, mqttIp);
			res = true;
		}
		if (current_romaconf->current_ServicePort != mqttPort)
		{
			dzlog_info("ActivationMain current_romaconf->current_ServicePort[%d] != mqttPort[%d]", current_romaconf->current_ServicePort, mqttPort);
			res = true;
		}
	}
	if (strcmp(current_romaconf->current_Name, deviceAuthUser) != 0)
	{
		dzlog_info("ActivationMain current_romaconf->current_Name[%s] deviceAuthUser[%s]", current_romaconf->current_Name, deviceAuthUser);
		res = true;
	}
	if (strcmp(current_romaconf->current_DeviceSecret, deviceAuthSecret) != 0)
	{
		dzlog_info("ActivationMain current_romaconf->current_DeviceSecret[%s] deviceAuthSecret[%s]", current_romaconf->current_DeviceSecret, deviceAuthSecret);
		res = true;
	}
	if (strcmp(current_romaconf->current_DevId, deviceId) != 0)
	{
		dzlog_info("ActivationMain current_romaconf->current_DevId[%s] deviceId[%s]", current_romaconf->current_DevId, deviceId);
		res = true;
	}

	return res;
}

int toSetRomaConfig(char* connectserver, char* connectreginfo, char* resMsg)
{

	FILE* file = fopen("/PowerHarmony/SMC/Connection/connectserver.json", "w");
	if (!file)
	{
		perror("Error opening file for writing");
		return -1;
	}
	fprintf(file, "%s", connectserver);
	fclose(file);

	FILE* file1 = fopen("/PowerHarmony/SMC/Connection/connectreginfo.json", "w");
	if (!file1)
	{
		perror("Error opening file for writing");
		return -1;
	}
	fprintf(file1, "%s", connectreginfo);
	fclose(file1);

	char trinity[256] = { 0 };
	sprintf(trinity, "chown -R tmp:tmp %s", "/PowerHarmony/SMC/Connection/");
	system(trinity);
	memset(trinity, 0, 256);
	sprintf(trinity, "chmod -R 766 %s", "/PowerHarmony/SMC/Connection/");
	system(trinity);

	return 1;
}

static int getDiskUsage(char* pid, char* disk)
{

	// printf("++++++++++++++++++++++++++++++++++++++getDiskUsage pid[%s]\n", pid);

	char dir[64] = { 0 };
	sprintf(dir, "/proc/%s/status", pid);
	struct stat st = { 0 };
	if (stat(dir, &st) == -1)
	{
		return -1;
	}

	char cmd[128] = { 0 };
	FILE* fp = NULL;
	sprintf(cmd, "cat /proc/%s/status | grep VmSize", pid);
	if ((fp = popen(cmd, "r")) == NULL)
	{
		pclose(fp);
		return NULL;
	}
	char buf[255] = { 0 };
	int i = 0;
	// printf("111111111111111111111111111111\n");
	while (fgets(buf, 255, fp) != NULL)
	{
		// printf("getDiskUsage buf[%s]\n", buf);
		char* p = strstr(buf, "VmSize:");
		if (!p)
		{
			continue;
		}
		char* token = strtok(p + strlen("VmSize:"), " ");
		while (token != NULL)
		{
			if (i == 1)
			{
				strcpy(disk, token);
				pclose(fp);
				// printf("------------------------------getDiskUsage pid[%s] token[%s]\n", pid, token);

					//后面计算需要用到g_disk_total，新增判断g_disk_total 值为0时，去获取磁盘总量
				if (g_disk_total == 0)
				{
					char result[512] = { 0 };
					int ret;

					// 直接使用MB单位
					ret = popenCmd("df -m | awk '{t+=$2; u+=$3; a+=$4} END{printf \"%d %d %d\", t, u, a}'", result);

					if (ret != 0)
						return -1;
					unsigned long total = 0, used = 0, available = 0;
					long free = 0;
					// 解析结果
					if (sscanf(result, "%lu %lu %lu", &total, &used, &available) != 3)
					{
						return -1;
					}
					g_disk_total = total;
				}
				return 0;
			}

			// printf("------------------------------getDiskUsage i[%d] pid[%s] token[%s]\n",i,pid,token);
			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
	}

	pclose(fp);

	// printf("------------------------------getDiskUsage\n");
	return -1;
}
static int getError(char* pid, char* error)
{
	// printf("gggggggggggggggggggggggggggggggggggggggggggg   getError pid[%s]\n", pid);
	char dir[64] = { 0 };
	sprintf(dir, "/proc/%s/status", pid);
	struct stat st = { 0 };
	if (stat(dir, &st) == -1)
	{
		return -1;
	}
	char cmd[128] = { 0 };
	FILE* fp = NULL;
	sprintf(cmd, "cat /proc/%s/status | grep State", pid);
	if ((fp = popen(cmd, "r")) == NULL)
	{
		pclose(fp);
		return NULL;
	}
	char buf[255] = { 0 };
	int i = 0;

	while (fgets(buf, 255, fp) != NULL)
	{
		char* p = strstr(buf, "State:");
		if (!p)
		{
			continue;
		}
		char* token = strtok(p + strlen("State:"), " ");
		while (token != NULL)
		{
			if (i == 0)
			{
				strcpy(error, token);
				// printf("gggggggggggggggggggggggggggggggggggggggggggg   error[%s]\n", error);
				pclose(fp);
				return 0;
			}

			/* Get next token: */
			token = strtok(NULL, " ");
			i++;
		}
	}

	pclose(fp);
	return -1;
}

// 获取进程CPU时间
int get_process_cpu_time(pid_t pid, cpu_time_t* cpu_time)
{
	char stat_path[64];
	char buffer[1024];

	snprintf(stat_path, sizeof(stat_path), "/proc/%d/stat", pid);

	FILE* fp = fopen(stat_path, "r");
	if (fp == NULL)
	{
		return -1;
	}

	if (fgets(buffer, sizeof(buffer), fp) != NULL)
	{
		char* token;
		int i;
		token = strtok(buffer, " ");
		// 第14项是utime，第15项是stime
		for (i = 1; i < 14; i++)
			token = strtok(NULL, " ");

		cpu_time->utime = strtoul(token, NULL, 10);
		token = strtok(NULL, " ");
		cpu_time->stime = strtoul(token, NULL, 10);
		clock_gettime(CLOCK_MONOTONIC, &cpu_time->timestamp);
	}

	fclose(fp);
	return 0;
}

// 计算CPU使用率
float calculate_cpu_usage(cpu_time_t* prev, cpu_time_t* curr)
{
	unsigned long time_diff = (curr->utime + curr->stime) - (prev->utime + prev->stime);

	// 计算实际经过的时间（纳秒）
	long time_elapsed_ns = (curr->timestamp.tv_sec - prev->timestamp.tv_sec) * 1000000000L + (curr->timestamp.tv_nsec - prev->timestamp.tv_nsec);

	// 转换为秒
	float time_elapsed_s = time_elapsed_ns / 1000000000.0;
	if (time_elapsed_s <= 0)
	{
		return 0.0;
	}
	// 获取系统CPU时钟频率
	long hz = sysconf(_SC_CLK_TCK);

	// 计算CPU使用率
	return ((float)time_diff / hz) / time_elapsed_s * 100.0;
}

// 获取指定进程的CPU使用率
int get_process_cpu_usage(pid_t pid, char* result)
{
	cpu_time_t prev_time, curr_time;

	// 第一次采样
	if (get_process_cpu_time(pid, &prev_time) < 0)
	{
		return -1;
	}

	// 等待指定的时间间隔
	// usleep((useconds_t)(interval_seconds * 1000000));
	sleep(2);

	// 第二次采样
	if (get_process_cpu_time(pid, &curr_time) < 0)
	{
		return -1;
	}
	float tmp = calculate_cpu_usage(&prev_time, &curr_time);
	snprintf(result, sizeof(result), "%.2f", tmp);
	return 1;
}

// 获取指定进程的内存使用率
int get_process_memory_usage(pid_t pid, char* result)
{
	char status_path[64];
	char buffer[256];
	unsigned long vm_rss = 0;	 // 实际物理内存使用
	unsigned long total_mem = 0; // 系统总内存

	// 获取系统总内存
	FILE* fp = fopen("/proc/meminfo", "r");
	if (fp != NULL)
	{
		if (fgets(buffer, sizeof(buffer), fp) != NULL)
		{
			sscanf(buffer, "MemTotal: %lu", &total_mem);
		}
		fclose(fp);
	}
	else
	{
		return -1;
	}

	// 构建进程status文件路径
	snprintf(status_path, sizeof(status_path), "/proc/%d/status", pid);

	fp = fopen(status_path, "r");
	if (fp == NULL)
	{
		perror("Failed to open status file");
		return -1;
	}

	// 查找VmRSS行
	while (fgets(buffer, sizeof(buffer), fp))
	{
		if (strncmp(buffer, "VmRSS:", 6) == 0)
		{
			sscanf(buffer, "VmRSS: %lu", &vm_rss);
			break;
		}
	}
	fclose(fp);

	// 计算内存使用率（将KB转换为相同单位）
	float tmp = total_mem > 0 ? ((float)vm_rss / total_mem) * 100.0 : 0;
	sprintf(result, "%.2f", tmp);
	return 1;
}

int performanceReport(PS_DATA_REPORT_PROCESS2 result)
{
	dzlog_info("performanceReport+++++++++++++++++++++++++++++\n");
	int i = 0;
	char buf[255] = { 0 };

	int ret = 0;
	char pid[128] = { 0 };
	pid_t ipid = getpid();
	sprintf(pid, "%d", ipid);
	strcpy(result->pid, pid);

	ret = get_process_memory_usage(ipid, result->memUsage);
	ret = get_process_cpu_usage(ipid, result->cpuUsage);

	if (ret == 0)
	{
	}
	int ret3 = getDiskUsage(result->pid, result->diskUsage);
	if (ret3 == 0 && g_disk_total != 0)
	{
		float buf = 100 * atof(result->diskUsage) / (1024 * g_disk_total);
		sprintf(result->diskUsage, "%.2f", buf);
	}
	else
	{
		ret = -1;
	}
	return ret;
}

int performanceErrorReport(char* result)
{
	char pid[128] = { 0 };
	int i = 0;
	char buf[255] = { 0 };
	int ret = 0;

	pid_t ipid = getpid();
	sprintf(pid, "%d", ipid);
	int ret3 = getError(pid, result);
	if (ret3 == 0)
	{
		(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		
		if (strcmp(g_error, result) == 0)
		{
			// pclose(fp);
			return 0;
		}
		else
		{
			strcpy(g_error, result);
		}
	}
	return ret;
}

static int dataSample(PS_DATA_REPORT_CMD dataReportCmd)
{
	time_t nowtime;
	time(&nowtime);

	if (strcmp("cpuTemp", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[0].sdataRepordCmd ,dataReportCmd,sizeof(S_DATA_REPORT_CMD));
		if (nowtime - g_dataReportCmd[0].lastSampleTime > g_dataReportCmd[0].sdataRepordCmd.sampleFrequency)
		{
			g_dataReportCmd[0].lastSampleTime = nowtime;
			dataCommen(&cpuTemp2, &g_dataCommen[0]);
		}
	}
	else if (strcmp("cpuUsage", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[1].sdataRepordCmd ,dataReportCmd,sizeof(S_DATA_REPORT_CMD));
		if (nowtime - g_dataReportCmd[1].lastSampleTime > g_dataReportCmd[1].sdataRepordCmd.sampleFrequency)
		{
			g_dataReportCmd[1].lastSampleTime = nowtime;
			dataCommen(&cpuUsage2, &g_dataCommen[1]);
		}
	}
	else if (strcmp("memUsage", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[2].sdataRepordCmd ,dataReportCmd,sizeof(S_DATA_REPORT_CMD));
		if (nowtime - g_dataReportCmd[2].lastSampleTime > g_dataReportCmd[2].sdataRepordCmd.sampleFrequency)
		{
			g_dataReportCmd[2].lastSampleTime = nowtime;
			dataCommen(&memUsage2, &g_dataCommen[2]);
		}
	}
	else if (strcmp("diskUsage", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[3].sdataRepordCmd ,dataReportCmd,sizeof(S_DATA_REPORT_CMD));
		if (nowtime - g_dataReportCmd[3].lastSampleTime > g_dataReportCmd[3].sdataRepordCmd.sampleFrequency)
		{
			g_dataReportCmd[3].lastSampleTime = nowtime;
			dataCommen(&diskUsage2, &g_dataCommen[3]);
		}
	}
	else if (strcmp("NetLinkStatus", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[7].sdataRepordCmd ,dataReportCmd,sizeof(S_DATA_REPORT_CMD));
		if (nowtime - g_dataReportCmd[7].lastSampleTime > g_dataReportCmd[7].sdataRepordCmd.sampleFrequency)
		{
			g_dataReportCmd[7].lastSampleTime = nowtime;
			dataCommen(&netLink2, &g_dataCommen[4]);
			// printf("g_dataCommen[4].count[%d]\n", g_dataCommen[4].count);
			// dzlog_info("g_dataCommen[4].count[%d]\n", g_dataCommen[4].count);
		}
	}

	return 0;
}
static int dataReportUnit(PS_DATA_REPORT_CMD dataReportCmd, void* dataReport, int now)
{

	time_t nowtime;
	time(&nowtime);

	if (strcmp("cpuTemp", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[0] ,dataReportCmd,sizeof(g_dataReportCmd[0]));
		if (nowtime - g_dataReportCmd[0].lastReportTime > g_dataReportCmd[0].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[0].lastReportTime = nowtime;
			if (g_dataCommen[0].count <= 0)
				return 0;
			((PS_DATA_REPORT_NORMAL)dataReport)->min = g_dataCommen[0].min;
			((PS_DATA_REPORT_NORMAL)dataReport)->max = g_dataCommen[0].max;
			((PS_DATA_REPORT_NORMAL)dataReport)->current = g_dataCommen[0].current;
			((PS_DATA_REPORT_NORMAL)dataReport)->avg = g_dataCommen[0].sum / g_dataCommen[0].count;
			strcpy(((PS_DATA_REPORT_NORMAL)dataReport)->indicator, dataReportCmd->indicator);
			strcpy(((PS_DATA_REPORT_NORMAL)dataReport)->unit, "°C");
			memset(&g_dataCommen[0], 0, sizeof(S_DATA_REPORT_PARAM));
			return 1;
		}
	}
	else if (strcmp("cpuUsage", dataReportCmd->indicator) == 0)
	{
		if (nowtime - g_dataReportCmd[1].lastReportTime > g_dataReportCmd[1].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[1].lastReportTime = nowtime;
			if (g_dataCommen[1].count <= 0)
				return 0;
			/// top5

			S_DATA_REPORT_PROCESS result[10] = { 0 };
			float value = 0;
			int ret = top5CpuResult(result, &value);
			if (ret > 0)
			{
				// proCommen(value, &g_dataCommen[1]);
			}
			((PS_DATA_REPORT_TOP5)dataReport)->normal.min = g_dataCommen[1].min;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.max = g_dataCommen[1].max;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.current = g_dataCommen[1].current;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.avg = g_dataCommen[1].sum / g_dataCommen[1].count;
			strcpy(((PS_DATA_REPORT_TOP5)dataReport)->normal.indicator, dataReportCmd->indicator);
			strcpy(((PS_DATA_REPORT_TOP5)dataReport)->normal.unit, "%");
			int i = 0;
			for (i = 0; i < 10; ++i)
			{
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].pid, result[i].pid);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].pName, result[i].pName);
				// printf("000000000000000000000000000000000000000000000000000000result[%d].pName[%s]\n", i, result[i].pName);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].user, result[i].user);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].usage, result[i].cpuUsage);
			}
			memset(&g_dataCommen[1], 0, sizeof(S_DATA_REPORT_PARAM));
			return 1;
		}
	}
	else if (strcmp("memUsage", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[2] ,dataReportCmd,sizeof(g_dataReportCmd[2]));
		if (nowtime - g_dataReportCmd[2].lastReportTime > g_dataReportCmd[2].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[2].lastReportTime = nowtime;
			if (g_dataCommen[2].count <= 0)
				return 0;
			/// top5

			S_DATA_REPORT_PROCESS result[10] = { 0 };
			float value = 0;
			int ret = top5MemResult(result, &value);
			if (ret > 0)
			{
				// proCommen(value, &g_dataCommen[2]);
			}
			/// top5
			((PS_DATA_REPORT_TOP5)dataReport)->normal.min = g_dataCommen[2].min;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.max = g_dataCommen[2].max;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.current = g_dataCommen[2].current;
			((PS_DATA_REPORT_TOP5)dataReport)->normal.avg = g_dataCommen[2].sum / g_dataCommen[2].count;
			strcpy(((PS_DATA_REPORT_TOP5)dataReport)->normal.indicator, dataReportCmd->indicator);
			strcpy(((PS_DATA_REPORT_TOP5)dataReport)->normal.unit, "%");
			S_DATA_REPORT_MEM_SUM mem = { 0 };
			PS_DATA_REPORT_MEM_SUM p = getMemSum(&mem);
			if (p)
				memcpy(&(((PS_DATA_REPORT_TOP5)dataReport)->mem), p, sizeof(S_DATA_REPORT_MEM_SUM));
			int i = 0;
			for (i = 0; i < 10; ++i)
			{
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].pid, result[i].pid);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].pName, result[i].pName);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].user, result[i].user);
				strcpy(((PS_DATA_REPORT_TOP5)dataReport)->top[i].usage, result[i].memUsage);
			}
			memset(&g_dataCommen[2], 0, sizeof(S_DATA_REPORT_PARAM));
			return 1;
		}
	}
	else if (strcmp("diskUsage", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[3] ,dataReportCmd,sizeof(g_dataReportCmd[3]));
		if (nowtime - g_dataReportCmd[3].lastReportTime > g_dataReportCmd[3].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[3].lastReportTime = nowtime;
			if (g_dataCommen[3].count <= 0)
				return 0;
			((PS_DATA_REPORT_NORMAL)dataReport)->min = g_dataCommen[3].min;
			((PS_DATA_REPORT_NORMAL)dataReport)->max = g_dataCommen[3].max;
			((PS_DATA_REPORT_NORMAL)dataReport)->current = g_dataCommen[3].current;
			((PS_DATA_REPORT_NORMAL)dataReport)->avg = g_dataCommen[3].sum / g_dataCommen[3].count;
			strcpy(((PS_DATA_REPORT_NORMAL)dataReport)->indicator, dataReportCmd->indicator);
			strcpy(((PS_DATA_REPORT_NORMAL)dataReport)->unit, "%");
			memset(&g_dataCommen[3], 0, sizeof(S_DATA_REPORT_PARAM));
			return 1;
		}
	}
	else if (strcmp("LTEModule", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[4] ,dataReportCmd,sizeof(g_dataReportCmd[4]));
		if (nowtime - g_dataReportCmd[4].lastReportTime > g_dataReportCmd[4].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[4].lastReportTime = nowtime;
			int ret = _4GInfoReport((PS_DATA_REPORT_4G)dataReport);
			_4GInfoReport2((PS_DATA_REPORT_4G)dataReport);
			// return ret;
			return 1;
		}
		else
		{
		}
	}
	else if (strcmp("etherModule", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[5] ,dataReportCmd,sizeof(g_dataReportCmd[5]));
		if (nowtime - g_dataReportCmd[5].lastReportTime > g_dataReportCmd[5].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[5].lastReportTime = nowtime;
			PS_DATA_REPORT_WIRE p = (PS_DATA_REPORT_WIRE)dataReport;

			int ret = 1;
			FILE* fp = fopen("/proc/net/dev", "r");
			if (!fp)
			{
				dzlog_error("open /proc/net/dev failed");
				ret = 0;
				return ret;
			}
			char line[300] = { 0 };
			// 读取每个网卡的信息
			while (fgets(line, sizeof(line), fp))
			{
				char* ptr = line;
				char interface[32];
				unsigned long long rx_bytes, rx_packets, tx_bytes, tx_packets;

				// 跳过行首空格
				while (isspace(*ptr))
					ptr++;

				// 解析网卡信息 *u表示跳过
				if (sscanf(ptr, "%[^:]: %llu %llu %*u %*u %*u %*u %*u %*u %llu %llu",
					interface,
					&rx_bytes,
					&rx_packets,
					&tx_bytes,
					&tx_packets) == 5)
				{
					// dzlog_debug("interface[%s] rx_bytes[%llu] rx_packets[%llu] tx_bytes[%llu] tx_packets[%llu]", interface, rx_bytes, rx_packets, tx_bytes, tx_packets);
					// 过滤出有线网卡
					if (strncmp(interface, "e", 1) == 0 || strncmp(interface, "b", 1) == 0)
					{
						strcpy(p->iface, interface);
						p->rxBytes = rx_bytes;
						p->txBytes = tx_bytes;
						p->rxPackets = rx_packets;
						p->txPackets = tx_packets;

						p->upSpeed = 0;
						p->downSpeed = 0;
						p->second = nowtime;

						PS_DATA_REPORT_WIRE p2 = getWireCard(p);
						if (p2)
						{
							time_t now_time;
							time(&now_time);
							p->upSpeed = (p->txBytes - p2->txBytes) / (now_time - p2->second);
							p->downSpeed = (p->rxBytes - p2->rxBytes) / (now_time - p2->second);
						}
						putWireCard(p);
						p++;
						ret++;
					}
				}
			}
			fclose(fp);
			return ret;
		}
	}
	else if (strcmp("DataSpace", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[6] ,dataReportCmd,sizeof(g_dataReportCmd[6]));
		if (nowtime - g_dataReportCmd[6].lastReportTime > g_dataReportCmd[6].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[6].lastReportTime = nowtime;
			int ret = diskInfoReport((PS_DATA_REPORT_DISK)dataReport);
			return ret;
		}
	}
	else if (strcmp("NetLinkStatus", dataReportCmd->indicator) == 0)
	{
		// memcpy(&g_dataReportCmd[7] ,dataReportCmd,sizeof(g_dataReportCmd[7]));
		if (nowtime - g_dataReportCmd[7].lastReportTime > g_dataReportCmd[7].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[7].lastReportTime = nowtime;
			if (g_dataCommen[4].count <= 0)
				return 0;
			if (g_dataNetworkCount > 0)
			{
				sumNetwork(g_dataNetwork, g_dataNetworkCount, &g_dataCommen[4], (PS_DATA_REPORT_NETWORK)dataReport);
				g_dataNetworkCount = 0;
				memset(&g_dataCommen[4], 0, sizeof(S_DATA_REPORT_PARAM));
				return 1;
			}
			return 0;
		}
	}
	else if (strcmp("processEvent", dataReportCmd->indicator) == 0)
	{

		if (nowtime - g_dataReportCmd[8].lastReportTime > g_dataReportCmd[8].sdataRepordCmd.reportFrequency || g_start_flag[0] == 0)
		{
			g_start_flag[0] = 1;
			g_dataReportCmd[8].lastReportTime = nowtime;
			int ret = propcessInfoReport((PS_DATA_REPORT_PROCESS_EVENT)dataReport);
			return ret;
		}
		else if (now == 1)
		{
			g_start_flag[0] = 1;
			g_dataReportCmd[8].lastReportTime = nowtime;
			int ret = propcessInfoReport((PS_DATA_REPORT_PROCESS_EVENT)dataReport);
			return ret;
		}
	}
	else if (strcmp("performanceEvent", dataReportCmd->indicator) == 0)
	{

		// //dzlog_info("dataReportCmd->indicator performanceEvent [%d]\n", g_dataReportCmd[14].sdataRepordCmd.reportFrequency);

		if (nowtime - g_dataReportCmd[14].lastReportTime > g_dataReportCmd[14].sdataRepordCmd.reportFrequency)
		{

			g_dataReportCmd[14].lastReportTime = nowtime;
			int ret = performanceReport((PS_DATA_REPORT_PROCESS2)dataReport);
			return ret;
		}
	}
	else if (strcmp("performanceErrorEvent", dataReportCmd->indicator) == 0)
	{
		if (nowtime - g_dataReportCmd[15].lastReportTime > g_dataReportCmd[15].sdataRepordCmd.reportFrequency)
		{

			g_dataReportCmd[15].lastReportTime = nowtime;
			int ret = performanceErrorReport((char*)dataReport);
			return ret;
		}
	}
	else if (strcmp("serviceEvent", dataReportCmd->indicator) == 0)
	{
		if (now == 1)
		{
			dzlog_info("serviceEvent 2");
			//g_start_flag[1] = 1;
			//g_dataReportCmd[9].lastReportTime = nowtime;
			dzlog_info("serverInfoReport start dataReport[%p]", dataReport);
			int ret = -1;
			ret = serverInfoReport((PS_DATA_REPORT_SERVER_EVENT)dataReport);
			//ret = serverInfoReport(dataReport);
			return ret;
			//return -1;
		}
		else if (nowtime - g_dataReportCmd[9].lastReportTime > g_dataReportCmd[9].sdataRepordCmd.reportFrequency || g_start_flag[1] == 0)
		{
			dzlog_info("serviceEvent 3");
			g_start_flag[1] = 1;
			g_dataReportCmd[9].lastReportTime = nowtime;
			dzlog_info("serverInfoReport start 2 dataReport[%p]", dataReport);
			int ret = serverInfoReport((PS_DATA_REPORT_SERVER_EVENT)dataReport);
			//int ret = serverInfoReport(dataReport);
			return ret;
		}
	}
	else if (strcmp("netstatEvent", dataReportCmd->indicator) == 0)
	{

		if (nowtime - g_dataReportCmd[10].lastReportTime > g_dataReportCmd[10].sdataRepordCmd.reportFrequency || g_start_flag[2] == 0)
		{
			g_start_flag[2] = 1;
			g_dataReportCmd[10].lastReportTime = nowtime;
			int ret = portInfoReport((PS_DATA_REPORT_PORT_EVENT)dataReport);
			return ret;
		}
		else if (now == 1)
		{
			g_start_flag[2] = 1;
			g_dataReportCmd[10].lastReportTime = nowtime;
			int ret = portInfoReport((PS_DATA_REPORT_PORT_EVENT)dataReport);
			return ret;
		}
	}
	else if (strcmp("KeepAlive", dataReportCmd->indicator) == 0)
	{
		if (nowtime - g_dataReportCmd[11].lastReportTime > g_dataReportCmd[11].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[11].lastReportTime = nowtime;
			int ret = 1;
			return ret;
		}
	}
	else if (strcmp("ContainerRuntimeData", dataReportCmd->indicator) == 0)
	{
		if (nowtime - g_dataReportCmd[12].lastReportTime > g_dataReportCmd[12].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[12].lastReportTime = nowtime;
			int ret = containerInfoReport((PS_DATA_REPORT_CONTAINER_EVENT)dataReport);
			return ret;
		}
	}
	else if (strcmp("AppRuntimeData", dataReportCmd->indicator) == 0)
	{
		if (nowtime - g_dataReportCmd[13].lastReportTime > g_dataReportCmd[13].sdataRepordCmd.reportFrequency)
		{
			g_dataReportCmd[13].lastReportTime = nowtime;
			int ret = appInfoReport((PS_DATA_REPORT_CONTAINER_EVENT)dataReport);
			return ret;
		}
		else if (now == 1)
		{
			g_dataReportCmd[13].lastReportTime = nowtime;
			int ret = appInfoReport((PS_DATA_REPORT_CONTAINER_EVENT)dataReport);
			return ret;
		}
		else
		{
			return -1;
		}
	}
	return 0;
}

void setDiskReportTime()
{
	time_t nowtime;
	time(&nowtime);
	g_dataReportCmd[6].lastReportTime = nowtime;
}

static void init()
{
	time_t nowtime;
	time(&nowtime);
	strcpy(g_dataReportCmd[0].sdataRepordCmd.indicator, "cpuTemp");
	g_dataReportCmd[0].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[0].sdataRepordCmd.reportFrequency = 900; //温度15分钟上报一次
	g_dataReportCmd[0].lastSampleTime = nowtime;
	g_dataReportCmd[0].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[1].sdataRepordCmd.indicator, "cpuUsage");
	g_dataReportCmd[1].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[1].sdataRepordCmd.reportFrequency = 900; //使用率15分钟上报一次
	g_dataReportCmd[1].lastSampleTime = nowtime;
	g_dataReportCmd[1].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[2].sdataRepordCmd.indicator, "memUsage");
	g_dataReportCmd[2].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[2].sdataRepordCmd.reportFrequency = 900;//内存15分钟上报一次
	g_dataReportCmd[2].lastSampleTime = nowtime;
	g_dataReportCmd[2].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[3].sdataRepordCmd.indicator, "diskUsage");
	g_dataReportCmd[3].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[3].sdataRepordCmd.reportFrequency = 900;//磁盘使用率15分钟上报一次
	g_dataReportCmd[3].lastSampleTime = nowtime;
	g_dataReportCmd[3].lastReportTime = nowtime;
	///
	strcpy(g_dataReportCmd[4].sdataRepordCmd.indicator, "LTEModule");
	//g_dataReportCmd[4].sdataRepordCmd.sampleFrequency = 10;
	//g_dataReportCmd[4].sdataRepordCmd.reportFrequency = 15; 
	g_dataReportCmd[4].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[4].sdataRepordCmd.reportFrequency = 900; //有线网卡流量信息15分钟上报一次
	g_dataReportCmd[4].lastSampleTime = nowtime;
	g_dataReportCmd[4].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[5].sdataRepordCmd.indicator, "etherModule");
	g_dataReportCmd[5].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[5].sdataRepordCmd.reportFrequency = 900; //有线网卡流量信息15分钟上报一次
	g_dataReportCmd[5].lastSampleTime = nowtime;
	g_dataReportCmd[5].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[6].sdataRepordCmd.indicator, "DataSpace");
	g_dataReportCmd[6].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[6].sdataRepordCmd.reportFrequency = 3600;  //60分钟一次
	g_dataReportCmd[6].lastSampleTime = nowtime;
	g_dataReportCmd[6].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[7].sdataRepordCmd.indicator, "NetLinkStatus");
	g_dataReportCmd[7].sdataRepordCmd.sampleFrequency = 600;
	g_dataReportCmd[7].sdataRepordCmd.reportFrequency = 900;//网络监测15分钟上报一次
	g_dataReportCmd[7].lastSampleTime = nowtime;
	g_dataReportCmd[7].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[8].sdataRepordCmd.indicator, "processEvent");
	g_dataReportCmd[8].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[8].sdataRepordCmd.reportFrequency = 43200;//进程监控12小时上报一次
	g_dataReportCmd[8].lastSampleTime = nowtime;
	g_dataReportCmd[8].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[9].sdataRepordCmd.indicator, "serviceEvent");
	g_dataReportCmd[9].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[9].sdataRepordCmd.reportFrequency = 86400;//服务监控24小时上报一次
	g_dataReportCmd[9].lastSampleTime = nowtime;
	g_dataReportCmd[9].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[10].sdataRepordCmd.indicator, "netstatEvent");
	g_dataReportCmd[10].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[10].sdataRepordCmd.reportFrequency = 900;//网络端口监控15分钟/次
	g_dataReportCmd[10].lastSampleTime = nowtime;
	g_dataReportCmd[10].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[11].sdataRepordCmd.indicator, "KeepAlive");
	g_dataReportCmd[11].sdataRepordCmd.sampleFrequency = 10;
	g_dataReportCmd[11].sdataRepordCmd.reportFrequency = 30;//终端心跳30秒上报一次
	g_dataReportCmd[11].lastSampleTime = nowtime;
	g_dataReportCmd[11].lastReportTime = nowtime;
	/// docker
	strcpy(g_dataReportCmd[12].sdataRepordCmd.indicator, "ContainerRuntimeData");
	g_dataReportCmd[12].sdataRepordCmd.sampleFrequency = 60;
	g_dataReportCmd[12].sdataRepordCmd.reportFrequency = 900;
	g_dataReportCmd[12].lastSampleTime = nowtime;
	g_dataReportCmd[12].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[13].sdataRepordCmd.indicator, "AppRuntimeData");
	g_dataReportCmd[13].sdataRepordCmd.sampleFrequency = 60;
	g_dataReportCmd[13].sdataRepordCmd.reportFrequency = 3600;//微应用监控60分钟上报一次
	g_dataReportCmd[13].lastSampleTime = nowtime;
	g_dataReportCmd[13].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[14].sdataRepordCmd.indicator, "performanceEvent");
	g_dataReportCmd[14].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[14].sdataRepordCmd.reportFrequency = 900;//鹰眼自监测15分钟上报一次
	g_dataReportCmd[14].lastSampleTime = nowtime;
	g_dataReportCmd[14].lastReportTime = nowtime;
	strcpy(g_dataReportCmd[15].sdataRepordCmd.indicator, "performanceErrorEvent");
	g_dataReportCmd[15].sdataRepordCmd.sampleFrequency = 30;
	g_dataReportCmd[15].sdataRepordCmd.reportFrequency = 900;//鹰眼自监测15分钟上报一次
	g_dataReportCmd[15].lastSampleTime = nowtime;
	g_dataReportCmd[15].lastReportTime = nowtime;

	//	//定时器初始化
	custom_timer[0].interval_collect = 15 * 60 * 1000;
	custom_timer[0].interval_send = 15 * 60 * 1000;

	/// docker
	///
	g_start_flag[0] = 0;
	g_start_flag[1] = 0;
	g_start_flag[2] = 0;
	/////
	char* indicatorArr[17] = { "cpuTemp", "cpuUsage", "memUsage", "diskUsage", "LTEModule", "etherModule",
							  "DataSpace", "NetLinkStatus", "processEvent", "serviceEvent", "netstatEvent",
								"KeepAlive", "ContainerRuntimeData","AppRuntimeData","performanceEvent","performanceErrorEvent",
								"CalculateTotalTraffic" };
	char* frequencyArr[2] = { "samplefrequency:", "reportfrequency:" };
	char value[64] = { 0 };
	int i = 0;
	int j = 0;
	for (i = 0; i < 2; ++i)
	{
		for (j = 0; j < 17; ++j)
		{
			char key[128] = { 0 };
			strcat(key, frequencyArr[i]);
			strcat(key, indicatorArr[j]);
			memset(value, 0, sizeof(value));
			int ret = getConfTerminal(key, value);
			dzlog_info("getConfTerminal key[%s],value[%s]", key, value);
			if (ret == 0)
			{
				if (i == 0)
				{
					g_dataReportCmd[j].sdataRepordCmd.sampleFrequency = atoi(value);
				}
				else if (i == 1)
				{
					g_dataReportCmd[j].sdataRepordCmd.reportFrequency = atoi(value);
					if (j == 12) // 统计流量上报的频率
					{
						custom_timer[0].interval_send = atoi(value) * 1000;
					}
				}
			}
		}
	}
	dzlog_info("getConfTerminal end");
}
int updateCmd(PS_DATA_REPORT_CMD dataReportCmd)
{
	if (strcmp("cpuTemp", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[0].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("cpuUsage", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[1].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("memUsage", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[2].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("diskUsage", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[3].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("LTEModule", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[4].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("etherModule", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[5].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("DataSpace", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[6].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("NetLinkStatus", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[7].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("processEvent", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[8].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("serviceEvent", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[9].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("netstatEvent", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[10].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("KeepAlive", dataReportCmd->indicator) == 0)
	{
		memcpy(&g_dataReportCmd[11].sdataRepordCmd, dataReportCmd, sizeof(S_DATA_REPORT_CMD));
	}
	else if (strcmp("CalculateTotalTraffic", dataReportCmd->indicator) == 0)
	{
		uv_timer_stop(&custom_timer[0].timer_collect);
		custom_timer[0].interval_send = dataReportCmd->reportFrequency * 1000;
		uv_timer_start(&custom_timer[0].timer_collect, timer0_callback, 0, custom_timer[0].interval_send); //
	}
	else
	{
		return -1;
	}
	char key[128] = { 0 };
	snprintf(key, sizeof(key), "samplefrequency:%s", dataReportCmd->indicator);
	setConfTerminal(key, dataReportCmd->sampleFrequency);
	snprintf(key, sizeof(key), "reportfrequency:%s", dataReportCmd->indicator);
	setConfTerminal(key, dataReportCmd->reportFrequency);

	return 0;
}

int dataReport(PS_DATA_REPORT_CMD dataReportCmd, void* dataReport, int now)
{
	if (!dataReportCmd)
	{
		return -1;
	}
	static int flag = 0;
	if (flag == 0)
	{
		flag = 1;
		init();
	}
	dataSample(dataReportCmd);

	return dataReportUnit(dataReportCmd, dataReport, now);
}

int setAuthorized(char* type, char* result, char* portNumber)
{
	if (!result)
	{
		return -1;
	}
	char cmd[128] = { 0 };
	char path[128] = { 0 };
	int ret = -1;
	if (strcmp(portNumber, "all") == 0)
	{
		int i = 0;

		for (i = 0; i < 11; i++)
		{
			memset(path, 0, sizeof(path));
			sprintf(path, "/sys/bus/usb/devices/usb%d/authorized", i);
			struct stat st = { 0 };
			if (stat(path, &st) != -1)
			{
				memset(cmd, 0, sizeof(cmd));
				sprintf(cmd, "echo %s > %s", type, path);
				ret = popenSetAuthorized(cmd, result, path);
				(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
			}
		}
	}
	else if (strstr(portNumber, "usb"))
	{
		memset(path, 0, sizeof(path));
		sprintf(path, "/sys/bus/usb/devices/%s/authorized", portNumber);
		struct stat st = { 0 };
		if (stat(path, &st) != -1)
		{
			memset(cmd, 0, sizeof(cmd));
			sprintf(cmd, "echo %s > %s", type, path);
			ret = popenSetAuthorized(cmd, result, path);
			(result[strlen(result) - 1] == '\n') && (result[strlen(result) - 1] = '\0');
		}
	}
	else
	{
		ret = -1;
	}

	return ret;
}

int popenSetAuthorized(char* cmd, char* result, char* path)
{
	if (!cmd || strlen(cmd) == 0)
	{
		return -1;
	}
	FILE* write_fp = popen(cmd, "r");
	if (write_fp == NULL)
	{
		dzlog_info("popenCmd  start 1 4");
		return -3;
	}
	pclose(write_fp);

	char cmd_ret[128] = { 0 };
	sprintf(cmd_ret, "cat %s", path);
	FILE* read_fp = popen(cmd_ret, "r");
	if (read_fp == NULL)
	{
		dzlog_info("popenCmd  start 1 4");
		return -3;
	}

	char buf[32 + 1];
	memset(buf, 0, sizeof(buf));
	int len = fread(buf, 1, 32, read_fp);
	if (len <= 0)
	{
		pclose(read_fp);
		return 0;
	}

	pclose(read_fp);
	strcpy(result, buf);
	return 0;
}

void parse_net_dev(NetInterface* interfaces, int* count)
{
	bool has_ppp_interface = false;
	char line[256];

	FILE* fp0 = fopen("/proc/net/dev", "r");
	fgets(line, sizeof(line), fp0);
	fgets(line, sizeof(line), fp0);
	while (fgets(line, sizeof(line), fp0))
	{
		char ifname0[16];
		unsigned long long rx0, tx0;
		sscanf(line, "%15[^:]: %llu %*u %*u %*u %*u %*u %*u %*u %llu", ifname0, &rx0, &tx0);
		remove_spaces(ifname0);
		if (strstr(ifname0, "ppp"))
		{
			has_ppp_interface = true;
			break;
		}
	}
	fclose(fp0);

	FILE* fp = fopen("/proc/net/dev", "r");
	int idx = 0;
	// 跳过前两行标题
	fgets(line, sizeof(line), fp);
	fgets(line, sizeof(line), fp);
	while (fgets(line, sizeof(line), fp))
	{
		char ifname[16];
		unsigned long long rx, tx;
		sscanf(line, "%15[^:]: %llu %*u %*u %*u %*u %*u %*u %*u %llu", ifname, &rx, &tx);
		remove_spaces(ifname);
		// dzlog_info("parse_net_dev start 4 ifname[%s],rx[%llu],tx[%llu]", ifname, rx, tx);

		if (has_ppp_interface)
		{
			if (strstr(ifname, "ppp"))
			{
				strcpy(interfaces[idx].name, ifname);
				interfaces[idx].rx_prev = rx;
				interfaces[idx].tx_prev = tx;
				interfaces[idx].rx_total = 0;
				interfaces[idx].tx_total = 0;
				interfaces[idx].deltarx = 0;
				interfaces[idx].deltatx = 0;
				idx++;
			}
		}
		else
		{ // 这个else仅仅作为调试，因开发环境设备并无从无线接入的设备
			if (strstr(ifname, "lo") || strstr(ifname, "gmac0") || strstr(ifname, "tunl0") || strstr(ifname, "usb0"))
				continue;
			if (strcmp(ifname, "eth0") == 0 || strcmp(ifname, "eth1") == 0)
			{
				strcpy(interfaces[idx].name, ifname);
				interfaces[idx].rx_prev = rx;
				interfaces[idx].tx_prev = tx;
				interfaces[idx].rx_total = 0;
				interfaces[idx].tx_total = 0;
				interfaces[idx].deltarx = 0;
				interfaces[idx].deltatx = 0;
				idx++;
			}
		}

		if (idx >= 15)
			break;
	}

	*count = idx;
	fclose(fp);
}

void parse_net_dev_b(NetInterface* interfaces, int* count)
{
	char line[256];
	FILE* fp = fopen("/proc/net/dev", "r");
	int idx = 0;
	// 跳过前两行标题
	fgets(line, sizeof(line), fp);
	fgets(line, sizeof(line), fp);
	while (fgets(line, sizeof(line), fp))
	{
		char ifname[16];
		unsigned long long rx, tx;
		sscanf(line, "%15[^:]: %llu %*u %*u %*u %*u %*u %*u %*u %llu", ifname, &rx, &tx);
		remove_spaces(ifname);
		if (strstr(ifname, "ppp"))
		{
			strcpy(interfaces[idx].name, ifname);
			interfaces[idx].rx_prev = rx;
			interfaces[idx].tx_prev = tx;
			interfaces[idx].rx_total = 0;
			interfaces[idx].tx_total = 0;
			interfaces[idx].deltarx = 0;
			interfaces[idx].deltatx = 0;
			idx++;
		}
		if (idx >= 2)
			break;
	}

	*count = idx;
	fclose(fp);
}


int get_net_interface_rates(PS_DATA_REPORT_WIRE dataReport)
{
	PS_DATA_REPORT_WIRE p = dataReport;
	int ret = 0;
	FILE* fp = fopen("/proc/net/dev", "r");
	if (!fp)
	{
		dzlog_error("open /proc/net/dev failed");
		ret = -1;
		return ret;
	}
	char line[128] = { 0 };
	// 读取每个网卡的信息
	while (fgets(line, sizeof(line), fp))
	{
		char* ptr = line;
		char interface[32];
		unsigned long long rx_bytes, rx_packets, tx_bytes, tx_packets;

		// 跳过行首空格
		while (isspace(*ptr))
			ptr++;

		// 解析网卡信息 *u表示跳过
		if (sscanf(ptr, "%[^:]: %llu %llu %*u %*u %*u %*u %*u %*u %llu %llu",
			interface,
			&rx_bytes,
			&rx_packets,
			&tx_bytes,
			&tx_packets) == 5)
		{
			if (strncmp(interface, "e", 1) == 0 || strncmp(interface, "ppp", 3) == 0)
			{
				strcpy(p->iface, interface);
				p->rxBytes = rx_bytes;
				p->txBytes = tx_bytes;
				p->upSpeed = 0;
				p->downSpeed = 0;
				time_t nowtime;
				time(&nowtime);
				p->second = nowtime;

				PS_DATA_REPORT_WIRE p2 = getWireCard(p);
				if (p2)
				{
					time_t now_time;
					time(&now_time);
					p->upSpeed = (p->txBytes - p2->txBytes) / (now_time - p2->second);
					p->downSpeed = (p->rxBytes - p2->rxBytes) / (now_time - p2->second);
				}
				putWireCard(p);
				p++;
				ret++;
			}
		}
	}
	fclose(fp);

	return ret;
}

int StructToJson_TerminalTotalTraffic(char* ciMid, char* deviceSn, PNetInterface psTerminalRuntimeWire, char** pcJson, int count)
{
	cJSON* json = NULL;
	cJSON* service = NULL;
	cJSON* services = NULL;
	cJSON* dev = NULL;
	cJSON* devs = NULL;
	cJSON* data = NULL;
	cJSON* datas = NULL;
	json = cJSON_CreateObject();
	if (json)
	{
		cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
		cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());

		cJSON_AddStringToObject(dev, "deviceSn", deviceSn);
		cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
		cJSON_AddItemToArray(services, service = cJSON_CreateObject());

		cJSON_AddStringToObject(service, "mid", ciMid);
		char cTime[128] = { 0 };
		int ret = systemDate(cTime);
		cJSON_AddStringToObject(service, "dataTime", cTime);
		cJSON_AddStringToObject(service, "service", "CalculateTotalTraffic");
		cJSON_AddItemToObject(service, "data", datas = cJSON_CreateArray());

		int i = 0;
		for (i = 0; i < count; i++)
		{
			cJSON_AddItemToArray(datas, data = cJSON_CreateObject());
			cJSON_AddNumberToObject(data, "rx_total", psTerminalRuntimeWire->rx_total);
			cJSON_AddNumberToObject(data, "tx_total", psTerminalRuntimeWire->tx_total);
			cJSON_AddNumberToObject(data, "total", psTerminalRuntimeWire->rx_total + psTerminalRuntimeWire->tx_total);
			cJSON_AddNumberToObject(data, "deltarx", psTerminalRuntimeWire->deltarx);
			cJSON_AddNumberToObject(data, "deltatx", psTerminalRuntimeWire->deltatx);
			cJSON_AddStringToObject(data, "iface", psTerminalRuntimeWire->name);
			psTerminalRuntimeWire++;
		}

		{
			*pcJson = cJSON_PrintUnformatted(json);
		}

		cJSON_Delete(json);
		return 0;
	}
	else
	{
		return -1;
	}
}

void timer0_callback(uv_timer_t* handle)
{

	dzlog_info("timer0_callback start");
	int i = 0;
	int j = 0;
	NetInterface prev[10] = { 0 };
	NetInterface interfaces[10] = { 0 };
	memset(prev, 0, sizeof(prev));
	memset(interfaces, 0, sizeof(interfaces));

	int prev_count = SqlSearNetworkTrafficCOUNT();
	if (prev_count != 0)
	{
		SqlSearNetworkTraffic(prev);
	}
	// 获取当前数据
	parse_net_dev(&interfaces, &interfaces_count);

	// 首次运行不计算增量
	unsigned long long rx_diff = 0;
	unsigned long long tx_diff = 0;
	bool is_overflow = false;
	if (prev_count != 0)
	{
		for (i = 0; i < interfaces_count; i++)
		{
			for (j = 0; j < prev_count; j++)
			{
				if (strcmp(interfaces[i].name, prev[j].name) == 0)
				{
					if (interfaces[i].rx_prev < prev[j].rx_prev)
					{
						interfaces[i].rx_total = prev[j].rx_total + interfaces[i].rx_prev;
						interfaces[i].deltarx = interfaces[i].rx_prev;
					}
					else
					{
						interfaces[i].rx_total = prev[j].rx_total + (interfaces[i].rx_prev - prev[j].rx_prev);
						interfaces[i].deltarx = interfaces[i].rx_prev - prev[j].rx_prev;
					}
					if (interfaces[i].tx_prev < prev[j].tx_prev)
					{
						interfaces[i].tx_total = prev[j].tx_total + interfaces[i].tx_prev;
						interfaces[i].deltatx = interfaces[i].tx_prev;
					}
					else
					{
						interfaces[i].tx_total = prev[j].tx_total + (interfaces[i].tx_prev - prev[j].tx_prev);
						interfaces[i].deltatx = interfaces[i].tx_prev - prev[j].tx_prev;
					}
				}
			}
		}
	}
	else
	{
		for (i = 0; i < interfaces_count; i++)
		{
			interfaces[i].rx_total = 0;
			interfaces[i].tx_total = 0;
			interfaces[i].deltarx = interfaces[i].rx_prev;
			interfaces[i].deltatx = interfaces[i].tx_prev;
		}
	}

	// 保存当前值为历史数据
	int ff = SqlINSERTIntoNetworkTraffic(interfaces, interfaces_count);
	dzlog_info("timer0_callback start 21 ff[%d]", ff);

	if (prev_count == 0 || is_overflow)
	{
		return 0; // 第一次统计时，没有历史值，不进行上报
	}
	// 在这里组装报文并上报
	char* jsonb = NULL;
	char uuid[64] = { 0 };
	GF_GetGUID(uuid);
	int ret2 = StructToJson_TerminalTotalTraffic(uuid, g_mqtt_ob.clientInfo.device_id, interfaces, &jsonb, interfaces_count);
	ret2 = IOTA_SendMqtt("/v1/devices/device/network", jsonb, strlen(jsonb));
	free(jsonb);

	return 0;
}

void timer1_callback(uv_timer_t* handle)
{
	async_handle_start = true;
	dzlog_info("timer1_callback start");
	time_t now_time = time(NULL);
	if (monitor_start_time - now_time < 0)
	{
		dzlog_info("timer1_callback stop");
		uv_timer_stop(&custom_timer[1].timer_collect);
		uv_timer_stop(&custom_timer[1].timer_send);
		async_handle_start = false;
	}

	cJSON* json = NULL;
	cJSON* data = NULL;
	cJSON* network = NULL;
	cJSON* info = NULL;
	cJSON* info1 = NULL;
	cJSON* cpu_usage = NULL;
	cJSON* cpu_top5 = NULL;
	cJSON* top5_c = NULL;
	cJSON* mem_usage = NULL;
	cJSON* mem_top5 = NULL;
	cJSON* top5_m = NULL;
	json = cJSON_CreateObject();
	if (json)
	{
		char uuid[64] = { 0 };
		GF_GetGUID(uuid);
		cJSON_AddStringToObject(json, "mid", uuid);
		cJSON_AddStringToObject(json, "deviceSn", g_mqtt_ob.clientInfo.device_id);
		char cTime[128] = { 0 };
		int ret = systemDate(cTime);
		cJSON_AddStringToObject(json, "dataTime", cTime);
		cJSON_AddStringToObject(json, "service", "realTimeMonitoring");
		cJSON_AddItemToObject(json, "data", data = cJSON_CreateObject());

		//cpu温度 start
		cJSON* cpu_Temp = NULL;
		cJSON_AddItemToObject(data, "cpuTemp", cpu_Temp = cJSON_CreateObject());
		cJSON_AddNumberToObject(cpu_Temp, "min", g_realTime_cpuTemp.min);
		cJSON_AddNumberToObject(cpu_Temp, "max", g_realTime_cpuTemp.max);
		cJSON_AddNumberToObject(cpu_Temp, "avg", g_realTime_cpuTemp.sum / g_realTime_cpuTemp.count);
		cJSON_AddNumberToObject(cpu_Temp, "current", g_realTime_cpuTemp.current);
		//cpu温度 end

		S_DATA_REPORT_PARAM dataCommen = { 0 };
		// cpu使用率
		cJSON_AddItemToObject(data, "cpu_usage", cpu_usage = cJSON_CreateObject());
		cJSON_AddNumberToObject(cpu_usage, "current", g_realTime_cpuUsage.current);
		cJSON_AddItemToObject(cpu_usage, "top5", cpu_top5 = cJSON_CreateArray());

		int ii = 0;
		for (ii = 0; ii < 5; ii++)
		{
			cJSON_AddItemToArray(cpu_top5, top5_c = cJSON_CreateObject());

			cJSON_AddStringToObject(top5_c, "pid", g_realTime_cpuTop5[ii].pid);
			cJSON_AddStringToObject(top5_c, "pName", g_realTime_cpuTop5[ii].pName);
			cJSON_AddStringToObject(top5_c, "user", g_realTime_cpuTop5[ii].user);
			cJSON_AddNumberToObject(top5_c, "cpuUsage", atof(g_realTime_cpuTop5[ii].cpuUsage));
		}

		cJSON_AddItemToObject(data, "mem_usage", mem_usage = cJSON_CreateObject());
		memUsage2(&dataCommen);
		char memUsed_tmp[32] = { 0 };
		ret = memUsed(memUsed_tmp);
		cJSON_AddNumberToObject(mem_usage, "current", dataCommen.current);
		cJSON_AddItemToObject(mem_usage, "top5", mem_top5 = cJSON_CreateArray());
		int jj = 0;
		for (jj = 0; jj < 5; jj++)
		{
			cJSON_AddItemToArray(mem_top5, top5_m = cJSON_CreateObject());
			cJSON_AddStringToObject(top5_m, "pid", g_realTime_memTop5[jj].pid);
			cJSON_AddStringToObject(top5_m, "pName", g_realTime_memTop5[jj].pName);
			cJSON_AddStringToObject(top5_m, "user", g_realTime_memTop5[jj].user);
			cJSON_AddNumberToObject(top5_m, "mem_usage", atof(g_realTime_memTop5[jj].memUsage));
		}

		//磁盘相关 start 

		//cJSON_AddNumberToObject(data, "diskUsage", dataCommen.current);
		//
		cJSON* diskUsages_json = NULL;
		cJSON* diskUsage_json = NULL;
		cJSON_AddItemToObject(data, "diskUsage", diskUsages_json = cJSON_CreateArray());
		cJSON_AddItemToArray(diskUsages_json, diskUsage_json = cJSON_CreateObject());
		//总磁盘容量
		diskUsage2(&dataCommen);
		cJSON_AddStringToObject(diskUsage_json, "mountedOn", "all");
		cJSON_AddNumberToObject(diskUsage_json, "current", dataCommen.current);
		//各磁盘分区容量
		S_DATA_REPORT_DISK dataReport_tmp[30];
		ret = diskInfoReport(&dataReport_tmp);
		for (ii = 0; ii < ret; ii++)
		{
			cJSON_AddItemToArray(diskUsages_json, diskUsage_json = cJSON_CreateObject());
			cJSON_AddStringToObject(diskUsage_json, "mountedOn", dataReport_tmp[ii].mountedOn);
			double result = convert_string_to_double(dataReport_tmp[ii].usedPercent);
			cJSON_AddNumberToObject(diskUsage_json, "current", result);
		}
		//磁盘相关 end 

		cJSON_AddNumberToObject(data, "pkt_loss_rate", 1);
		cJSON_AddNumberToObject(data, "net_latency", 1);
		if (g_dataCommen[4].count > 0)
		{
			if (g_dataNetworkCount > 0)
			{
				S_DATA_REPORT_NETWORK dataReport;
				sumNetwork(g_dataNetwork, g_dataNetworkCount, &g_dataCommen[4], &dataReport);
				cJSON_AddNumberToObject(data, "pkt_loss_rate", dataReport.lossPct);
				cJSON_AddNumberToObject(data, "net_latency", dataReport.avg);
			}
		}

		// S_DATA_REPORT_4G result2 = {0};
		////_4GInfoReport(&result2);
		//_4GInfoReport2(&result2);
		cJSON_AddNumberToObject(data, "rsrp", atof(g_realTime_4G.rsrp));
		cJSON_AddNumberToObject(data, "rsrq", atof(g_realTime_4G.rsrq));
		cJSON_AddNumberToObject(data, "rssi", atof(g_realTime_4G.rssi));
		cJSON_AddNumberToObject(data, "sinr", atof(g_realTime_4G.sinr));
		cJSON_AddItemToObject(data, "network", network = cJSON_CreateArray());

		cJSON_AddItemToArray(network, info1 = cJSON_CreateObject());
		cJSON_AddNumberToObject(info1, "upSpeed", 0);
		cJSON_AddNumberToObject(info1, "downSpeed", 0);
		cJSON_AddStringToObject(info1, "iface", "eth0");
		S_DATA_REPORT_WIRE dataReport[5] = { 0 };
		ret = get_net_interface_rates(&dataReport);
		if (ret >= 0)
		{
			int ii = 0;
			for (ii = 0; ii < ret; ii++)
			{
				dataReport[ii].downSpeed;
				dataReport[ii].upSpeed;
				dataReport[ii].iface;
				if (strcmp(dataReport[ii].iface, "eth0") == 0)
				{
					cJSON_ReplaceItemInObject(info1, "upSpeed", cJSON_CreateNumber(dataReport[ii].upSpeed));
					cJSON_ReplaceItemInObject(info1, "downSpeed", cJSON_CreateNumber(dataReport[ii].downSpeed));
				}
				else
				{
					cJSON_AddItemToArray(network, info = cJSON_CreateObject());
					cJSON_AddNumberToObject(info, "upSpeed", dataReport[ii].upSpeed);
					cJSON_AddNumberToObject(info, "downSpeed", dataReport[ii].downSpeed);
					cJSON_AddStringToObject(info, "iface", dataReport[ii].iface);
				}
			}
		}
		char* pcJson;
		pcJson = cJSON_PrintUnformatted(json);
		IOTA_SendMqtt("/v1/devices/device/realTimeMonitoring", pcJson, strlen(pcJson));
		free(pcJson);
		cJSON_Delete(json);
		dzlog_info("timer1_callback end");
		return 0;
	}
	else
	{
		return -1;
	}

	return 0;
}

//定时查询CCO下子设备认证信息
void query_subdevice_callback(uv_timer_t *handle)
{
	dzlog_info("query_subdevice_callback start");
	QueryCcoSubDevice();
}

// 收集数据的耗时任务
void collect_data()
{
	dzlog_info("timer2_callback start");

	dataCommen(&cpuTemp2, &g_realTime_cpuTemp);

	// cpu使用率采集
	g_realTime_cpuUsage.current = 9.23;
	dataCommen(&cpuUsage2_b, &g_realTime_cpuUsage);

	// 无线信号质量采集
	// sprintf(g_realTime_4G.rsrp, "%s", "-86");
	// sprintf(g_realTime_4G.rsrq, "%s", "-12");
	// sprintf(g_realTime_4G.rssi, "%s", "-54");
	// sprintf(g_realTime_4G.sinr, "%s", "1");
	_4GInfoReport2(&g_realTime_4G);

	// cpu使用率top5采集
	float value = 0;
	int ret = top5CpuResult(g_realTime_cpuTop5, &value);

	// 内存使用率top5采集
	value = 0;
	ret = top5MemResult(g_realTime_memTop5, &value);
	dzlog_info("timer2_callback end");
}

// 工作回调：执行实际任务
void work_collect_cb(uv_work_t* req)
{
	// work_data_t* data = (work_data_t*)req->data;
	collect_data();
}

// 工作完成后的回调
void after_collect_cb(uv_work_t* req, int status)
{
	// work_data_t* data = (work_data_t*)req->data;
	// free(data);
	free(req);
	if (status < 0)
	{
		fprintf(stderr, "Collect work error: %s", uv_strerror(status));
	}
}

void timer2_callback(uv_timer_t* handle)
{
	uv_work_t* req = malloc(sizeof(uv_work_t));
	int r = uv_queue_work(global_loop, req, work_collect_cb, after_collect_cb);
	if (r < 0)
	{
		fprintf(stderr, "Work submit error: %s", uv_strerror(r));
		free(req);
	}
}

//实时监控数据上报功能的定时器
// 异步回调：在事件循环线程中添加定时器
void async_callback(uv_async_t* handle)
{
	dzlog_info("Adding new real-time monitoring timer");

	// 采集
	uv_timer_init(global_loop, &custom_timer[1].timer_collect); //
	custom_timer[1].interval_collect = 10 * 1000;
	uv_timer_start(&custom_timer[1].timer_collect, timer2_callback, 0, custom_timer[1].interval_collect); //

	// 上报
	uv_timer_init(global_loop, &custom_timer[1].timer_send); //
	custom_timer[1].interval_send = 4.7 * 1000;
	uv_timer_start(&custom_timer[1].timer_send, timer1_callback, 0, custom_timer[1].interval_send); //
}

// 初始化异步句柄
void init_async()
{
	uv_async_init(global_loop, &async_handle, async_callback);
}

void run_loop()
{
	/////////test
	//int re = -1;
	//char pcJson[512] = { 0 };
	//while (1)
	//{
	//	memset(pcJson, 0, 512);
	//	//读取文件，并发送报文
	//	re = get_file_json(pcJson, "./data.json");
	//	if (re < 0)
	//	{
	//		continue;
	//	}
	//	else
	//	{
	//		int ret2 = IOTA_SendMqtt("/v1/devices/030140201482000000000777/device/command", pcJson, strlen(pcJson));
	//	}
	//	usleep(1000*200);
	//}
	//////////test//////////////
	sleep(10);
	//init();
	global_loop = uv_default_loop(); // 获取默认事件循环
	init_async();
	collect_data(); // 执行一次，拿到值作为初始值（解决第一个点的问题）

	uv_timer_init(global_loop, &custom_timer[0].timer_collect); // 统计上报流量数据定时器
	//  启动定时器，第一个参数是定时器句柄，第二个参数是回调函数，第三个参数是初始延迟时间（毫秒），第四个参数是重复间隔时间（毫秒）
	uv_timer_start(&custom_timer[0].timer_collect, timer0_callback, 0, custom_timer[0].interval_send); //

	// 运行事件循环
	uv_run(global_loop, UV_RUN_DEFAULT);
	return 0;
}

void run_loop_v1()
{
	dzlog_info("run_loop_v1 start");

	// 记录开始时间，并每触发一次增加5分钟
	monitor_start_time = time(NULL);
	monitor_start_time = monitor_start_time + 5 * 60; // 直接加300秒

	// 启动定时器
	if (!async_handle_start)
	{
		dzlog_info("uv_async_send");
		uv_async_send(&async_handle);
	}

	return 0;
}


int StructToJson_TerminalIotInfo(char* ciMid, char* deviceSn, char* version, char* iotTlsMax, char* iotTlsCurrent, char** pcJson)
{
	cJSON* json = NULL;
	cJSON* service = NULL;
	cJSON* services = NULL;
	cJSON* dev = NULL;
	cJSON* devs = NULL;
	cJSON* data = NULL;

	json = cJSON_CreateObject();
	if (json)
	{
		cJSON_AddItemToObject(json, "devices", devs = cJSON_CreateArray());
		cJSON_AddItemToArray(devs, dev = cJSON_CreateObject());

		cJSON_AddStringToObject(dev, "deviceSn", deviceSn);
		cJSON_AddItemToObject(dev, "services", services = cJSON_CreateArray());
		cJSON_AddItemToArray(services, service = cJSON_CreateObject());

		cJSON_AddStringToObject(service, "mid", ciMid);
		char cTime[64] = { 0 };
		int ret = systemDate3(cTime);
		cJSON_AddStringToObject(service, "eventTime", cTime);
		cJSON_AddStringToObject(service, "service", "IotInfo");
		cJSON_AddItemToObject(service, "data", data = cJSON_CreateObject());
		cJSON_AddStringToObject(data, "iotversion", version);
		cJSON_AddStringToObject(data, "iotTlsMax", iotTlsMax);
		cJSON_AddStringToObject(data, "iotTlsCurrent", iotTlsCurrent);
		*pcJson = cJSON_PrintUnformatted(json);

		cJSON_Delete(json);
		return 0;
	}
	else
	{
		return -1;
	}
}
